From patchwork Thu Jul 25 23:24:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137159 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="WzGUxwYj"; 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 45vpGQ23czz9s4Y for ; Fri, 26 Jul 2019 09:25:02 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 795C0C6F; Thu, 25 Jul 2019 23:24:30 +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 321278D7 for ; Thu, 25 Jul 2019 23:24:28 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id CF6F6B0 for ; Thu, 25 Jul 2019 23:24:27 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id i18so23781516pgl.11 for ; Thu, 25 Jul 2019 16:24:27 -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=/ZeV+Wut2btzSdkAuaK8sgNT43pYVbic9Z6fDLqSTlE=; b=WzGUxwYjpp1AdnVbWP5/JRfOu1Q8jSArbqh5V9Rd00RvziENJrAC+nCR1+/BrhgkcT YX6A9zIl7kDw/AsMoy5epRC7gvC8v811iEAd5veyE3INHr5Q3J2KoHT4r/ThixnQS+7w +1tOi2CelifTA0gBosADvnGrz5WxRjLtu7OQ31e9fnjMGVbMBUeu49aO8yyjSPq9hgvK dX/ZOBAIDeEF2wDMZUj3jIwPPqDSkOOj127kF+ZQJSoURoqVFompJt3KEGoybz+PVBsy W8Z8rf4Ljz2kLbAfUqVv10x/4J0D63JmcBp1Vt/2DY8tLoKohF+NaNF25s6lnXzx1XfJ 9ggQ== 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=/ZeV+Wut2btzSdkAuaK8sgNT43pYVbic9Z6fDLqSTlE=; b=Vj9ziYocrzFMWv2U5n5kOb6K0xrWaG9bvcGTB2thejs15dtPbuVa0QALv40NGOuUZo 1EvtZGsBhtx2epZmvC/Iqx7X4JqjcNdAnFs3CQUXsQ6d7Rh6WNDnQZo0TUVU/POhajlG wwJjxHnZpfz62GAsa+eEyaFcMuV7gc7Dn81sRgAucinaRWyJQPGgZ9+gLD+mjxwyiFzR JuoMhxDOCo1RQwLC8XrOdkqpw1PO5L/LZ3T/jddHI8qp+tQm90qMwsr4kA8F/N9w6G2j rDjYs+WGopgfqQQURfsBZVg7G5OZiLI/AS0dv94BqXtUAvB0X8ELmbsXChYUi6RodToI nLVA== X-Gm-Message-State: APjAAAW6bHF6IoPrnNAjnRnxOdHMmdETa9XE/PiFJtP+pA9uIz3q11J/ QFdLQH0+JMxoiQWJyHplttdwCBpx X-Google-Smtp-Source: APXvYqyJdsOmyOBxwLJa1v/+LX55eEumjTV3Z0YZkJotjx+Jf914f1r9xuXNiwaXCTD+Fq6ZUh/BHw== X-Received: by 2002:aa7:81ca:: with SMTP id c10mr19281098pfn.185.1564097066991; Thu, 25 Jul 2019 16:24:26 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:25 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:03 -0700 Message-Id: <1564097054-72663-2-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 01/12] simap: Add utility function to help compare two simaps. 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 From: Ben Pfaff Signed-off-by: Ben Pfaff Acked-by: William Tu --- lib/simap.c | 15 ++++++++++++++- lib/simap.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/simap.c b/lib/simap.c index d634f8ed9eea..f404ece67703 100644 --- a/lib/simap.c +++ b/lib/simap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2017 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2017, 2019 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -242,6 +242,19 @@ simap_equal(const struct simap *a, const struct simap *b) return true; } +uint32_t +simap_hash(const struct simap *simap) +{ + uint32_t hash = 0; + + const struct simap_node *node; + SIMAP_FOR_EACH (node, simap) { + hash ^= hash_int(node->data, + hash_name(node->name, strlen(node->name))); + } + return hash; +} + static size_t hash_name(const char *name, size_t length) { diff --git a/lib/simap.h b/lib/simap.h index 5b4a2f39dca3..5e646e660782 100644 --- a/lib/simap.h +++ b/lib/simap.h @@ -70,6 +70,7 @@ bool simap_find_and_delete(struct simap *, const char *); const struct simap_node **simap_sort(const struct simap *); bool simap_equal(const struct simap *, const struct simap *); +uint32_t simap_hash(const struct simap *); #ifdef __cplusplus } From patchwork Thu Jul 25 23:24:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137160 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="nrh1PxC7"; 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 45vpH55YB8z9sBF for ; Fri, 26 Jul 2019 09:25:37 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 20D88CA1; Thu, 25 Jul 2019 23:24:32 +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 0A8A2C51 for ; Thu, 25 Jul 2019 23:24:30 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl1-f194.google.com (mail-pl1-f194.google.com [209.85.214.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 2A309B0 for ; Thu, 25 Jul 2019 23:24:29 +0000 (UTC) Received: by mail-pl1-f194.google.com with SMTP id ay6so24018961plb.9 for ; Thu, 25 Jul 2019 16:24:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Hs0vgDB56/tNv/Bwg0E8S/wbFOcQYoq1qLSCuMIq188=; b=nrh1PxC761jXTKeg1WqQ/mGl2ouMSxrvJNiadSmE/0TASpDxsYdNCM2EUHd3FYjXdZ Bq6ZgyEAMHZ5B+N06FFSQu4W0sb+xxnNj65zRNHqZy2y6WV4DozqDAj3YiPBZ87P/82T L5cPmIXiBZacpme3uVTDSnbKLxEpk21NMhBGdZN9J9nG9HYDFqFmZXeS/kQgWOHi5/zf 5vcqpByBaZ0spv+BBocZQQLnhPLMANMlvlHNtivOLH0fS8S7wpK18nbFzNb9GBW2o27g xvhOkIQiXqg+lq9EdXrk25jR5zvAuc+p2pVFHP6VZi2tcdWLe0gBAsff5YehgaFBNSYX R8Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Hs0vgDB56/tNv/Bwg0E8S/wbFOcQYoq1qLSCuMIq188=; b=MhU6fWEcKyICi4BhNkthABpVMRjMiZT8nxRsahqvEBiiUtNo8EcJmy/ZaYHLbUjB8c 8orpBMeB3EqiTB/kki9XNFCwHjsXS0GP/XoY6zGW5EDtQm1HLZNi4afqpbSJ53GXpEy9 weckhtsGm8Q0Kf3lFnPY4IizKhBkQY173euovZSQzd4DVJOfPWINNQbc3KUHosdGDEDj NHMGf0v9z8bVsC0eUVZZtMrtOeM7w8DKIiPYyazhZdftGVYWB1NVV8nA0glD/dWqIc3W A8MI1phPYyMdo4mgEwNi77PeIT3mvJN+Trry7krLyGsXAqQrhwKkEF8t50iLmiMrYCjh QIrw== X-Gm-Message-State: APjAAAVA7wAYSMRomR+gvsjtQfxVcrWRVZTymgQu5ekq/DIO0oxo/tzG +GXXyilfXue0lfeDR144a8vrhoY4 X-Google-Smtp-Source: APXvYqzxjpO8/hy8GteZR2z0V1V+zd32PMu89QxPr4ok8eEegwyoukWWb2lfyEC3cexjJ48uj8oozA== X-Received: by 2002:a17:902:2aa8:: with SMTP id j37mr88938050plb.316.1564097068251; Thu, 25 Jul 2019 16:24:28 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:27 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:04 -0700 Message-Id: <1564097054-72663-3-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 02/12] vswitchd: Add datapath, CT_Zone, and CT_Timeout_Policy tables. 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 From: Justin Pettit Signed-off-by: Justin Pettit --- vswitchd/vswitch.ovsschema | 44 +++++++- vswitchd/vswitch.xml | 254 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 249 insertions(+), 49 deletions(-) diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index f7c6eb8983cd..17aed1fc3ad1 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,9 +1,14 @@ {"name": "Open_vSwitch", - "version": "8.0.0", - "cksum": "3962141869 23978", + "version": "8.2.0", + "cksum": "2203523463 25517", "tables": { "Open_vSwitch": { "columns": { + "datapaths": { + "type": {"key": {"type": "string"}, + "value": {"type": "uuid", + "refTable": "Datapath"}, + "min": 0, "max": "unlimited"}}, "bridges": { "type": {"key": {"type": "uuid", "refTable": "Bridge"}, @@ -629,6 +634,41 @@ "min": 0, "max": "unlimited"}, "ephemeral": true}}, "indexes": [["target"]]}, + "Datapath": { + "columns": { + "datapath_version": { + "type": "string"}, + "ct_zones": { + "type": {"key": {"type": "integer", + "minInteger": 0, + "maxInteger": 65535}, + "value": {"type": "uuid", + "refTable": "CT_Zone"}, + "min": 0, "max": "unlimited"}}, + "external_ids": { + "type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}}}, + "CT_Zone": { + "columns": { + "timeout_policy": { + "type": {"key": {"type": "uuid", + "refTable": "CT_Timeout_Policy"}, + "min": 0, "max": 1}}, + "external_ids": { + "type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}}}, + "CT_Timeout_Policy": { + "columns": { + "timeouts": { + "type": {"key": "string", + "value": {"type" : "integer", + "minInteger" : 0, + "maxInteger" : 4294967295}, + "min": 0, "max": "unlimited"}}, + "external_ids": { + "type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}}, + "indexes": [["timeouts"]]}, "SSL": { "columns": { "private_key": { diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 027aee2f523b..7f1686a676aa 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -52,6 +52,13 @@ one record in the table. + + Map of datapath types to datapaths. The + column of the + table is used as a key for this map. The value points to a row in + the table. + + Set of bridges managed by the daemon. @@ -1192,53 +1199,11 @@ -

- Reports the version number of the Open vSwitch datapath in use. - This allows management software to detect and report discrepancies - between Open vSwitch userspace and datapath versions. (The column in the reports the Open vSwitch userspace version.) - The version reported depends on the datapath in use: -

- -
    -
  • - When the kernel module included in the Open vSwitch source tree is - used, this column reports the Open vSwitch version from which the - module was taken. -
  • - -
  • - When the kernel module that is part of the upstream Linux kernel is - used, this column reports <unknown>. -
  • - -
  • - When the datapath is built into the ovs-vswitchd - binary, this column reports <built-in>. A - built-in datapath is by definition the same version as the rest of - the Open VSwitch userspace. -
  • - -
  • - Other datapaths (such as the Hyper-V kernel datapath) currently - report <unknown>. -
  • -
- -

- A version discrepancy between ovs-vswitchd and the - datapath in use is not normally cause for alarm. The Open vSwitch - kernel datapaths for Linux and Hyper-V, in particular, are designed - for maximum inter-version compatibility: any userspace version works - with with any kernel version. Some reasons do exist to insist on - particular user/kernel pairings. First, newer kernel versions add - new features, that can only be used by new-enough userspace, e.g. - VXLAN tunneling requires certain minimal userspace and kernel - versions. Second, as an extension to the first reason, some newer - kernel versions add new features for enhancing performance that only - new-enough userspace versions can take advantage of. -

+ Reports the datapath version. This column is maintained for + backwards compatibility. The preferred locatation is the + column of the + table. The full documentation for this + column is there.
@@ -5560,6 +5525,201 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
+ +

+ Configuration for a datapath within . +

+

+ A datapath is responsible for providing the packet handling in Open + vSwitch. There are two primary datapath implementations used by + Open vSwitch: kernel and userspace. Kernel datapath + implementations are available for Linux and Hyper-V, and selected + as system in the column + of the table. The userspace datapath is used + by DPDK and AF-XDP, and is selected as netdev in the + column of the + table. +

+

+ A datapath of a particular type is shared by all the bridges that use + that datapath. Thus, configurations applied to this table affect + all bridges that use this datapath. +

+ + +

+ Reports the version number of the Open vSwitch datapath in use. + This allows management software to detect and report discrepancies + between Open vSwitch userspace and datapath versions. (The column in the reports the Open vSwitch userspace version.) + The version reported depends on the datapath in use: +

+ +
    +
  • + When the kernel module included in the Open vSwitch source tree is + used, this column reports the Open vSwitch version from which the + module was taken. +
  • + +
  • + When the kernel module that is part of the upstream Linux kernel is + used, this column reports <unknown>. +
  • + +
  • + When the datapath is built into the ovs-vswitchd + binary, this column reports <built-in>. A + built-in datapath is by definition the same version as the rest of + the Open VSwitch userspace. +
  • + +
  • + Other datapaths (such as the Hyper-V kernel datapath) currently + report <unknown>. +
  • +
+ +

+ A version discrepancy between ovs-vswitchd and the + datapath in use is not normally cause for alarm. The Open vSwitch + kernel datapaths for Linux and Hyper-V, in particular, are designed + for maximum inter-version compatibility: any userspace version works + with with any kernel version. Some reasons do exist to insist on + particular user/kernel pairings. First, newer kernel versions add + new features, that can only be used by new-enough userspace, e.g. + VXLAN tunneling requires certain minimal userspace and kernel + versions. Second, as an extension to the first reason, some newer + kernel versions add new features for enhancing performance that only + new-enough userspace versions can take advantage of. +

+
+ + + Configuration for connection tracking zones. Each pair maps from a + zone id to a configuration for that zone. Zone 0 applies + to the default zone (ie, the one used if a zone is not specified in + connection tracking-related OpenFlow matches and actions). + + + + The overall purpose of these columns is described under Common + Columns at the beginning of this document. + + + +
+ + + Connection tracking zone configuration + + + Connection tracking timeout policy for this zone. If timeout policy is + not specified, defaults to the timeout policy in the default zone. If + the timeout policy in default zone is not specified, defaults to the + default timeouts in the system. + + + + The overall purpose of these columns is described under Common + Columns at the beginning of this document. + + + +
+ + + Connection tracking timeout policy configuration + + + + The timeouts column contains key-value pairs used + to configure connection tracking timeouts in a datapath. + Key-value pairs that are not supported by a datapath are + ignored. + + + + + TCP SYN sent timeout. + + + + TCP SYN receive timeout. + + + + TCP established timeout. + + + + TCP FIN wait timeout. + + + + TCP close wait timeout. + + + + TCP last ACK timeout. + + + + TCP time wait timeout. + + + + TCP close timeout. + + + + TCP syn sent2 timeout. + + + + TCP retransmit timeout. + + + + TCP unacknowledgment timeout. + + + + + + First UDP packet timeout. + + + + The timeout in the state that source host sends more than one packet + but the destination host has never sent one backs. + + + + UDP packets seen in both directions timeout. + + + + + + First ICMP timeout. + + + + ICMP reply timeout. + + + + + + The overall purpose of these columns is described under Common + Columns at the beginning of this document. + + + +
+ SSL configuration for an Open_vSwitch. From patchwork Thu Jul 25 23:24:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137161 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="d6Do9Iva"; 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 45vpHq1pqHz9s4Y for ; Fri, 26 Jul 2019 09:26:15 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id B188ACB1; Thu, 25 Jul 2019 23:24:32 +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 6049AC59 for ; Thu, 25 Jul 2019 23:24:31 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 790FDB0 for ; Thu, 25 Jul 2019 23:24:30 +0000 (UTC) Received: by mail-pf1-f194.google.com with SMTP id r7so23505912pfl.3 for ; Thu, 25 Jul 2019 16:24:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=K5g0KspmNFcWm13jVNvhUz5kBpOrAecGIHFNDvXimRY=; b=d6Do9IvaMGxOkU0ynwu7SMzXw1H9AkTsA9Dp5nqgscfcXqyYjcTwKCg9ZanksBnc3Y K/FI+8BLR2VTk3mV29qsdBnzO/rsRt3TcTIIjSbuU/yZu64SMBafBMAqqABV2LUVMKb3 8wi4dZnH50vNv1HKrn1bO/hkfQ1xElSBLhnb+W6f9vv7QKEdgmT96I87Ge4agZZIb9rF TXBXRbnl92BhKq+wRJ7ILQTWzDp7NRk15CWCJe001LfyotsCiFevUCoCFIcxeZbqMfrK 1yu0EWSyE0bc5Uj78uDlDDNdWeAqkJCjh/kQxJ7FrQ/aqqP0IEQ7QkuXaX2ub+ybIbEc YPlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=K5g0KspmNFcWm13jVNvhUz5kBpOrAecGIHFNDvXimRY=; b=jUADCKuw41GScK0je2/k18SgWKuYuaRbOyonxOeLoj2OMREpLd5jxVE3hi/+e4pfLL 2EXwqdNjned3MlCGVaul6enbE8vrnXxk5Hk6GltM4PqlVMyfuAotRUc98uc39jw79cqb MFCT3Spyq+y7ED/OaWkN0sKKNDcpa64I3K/aFts8gGyhtW5NVXDMX13xKVRaU0F4NWbq XTqWt9Aic5O318ekB5VhBR7amzbAahsp/B07SKM37DAbtRnwckbdCkAbaTKHn9c/Uaex bF5e3ZM1FVnjHlncl8uqkhuI8lYViKd1pLB8BL+PmhUNAKsNmtJtcN2Dl756kyC8ZitH Uctw== X-Gm-Message-State: APjAAAVF1nz2o101caOFkvrW4vpFpzPQx+N/sd4yQYZB2D1l/vVkZ1rp SeYJQ4yuIhGftiqzV1DPRkdnBU0x X-Google-Smtp-Source: APXvYqx7w34kq/PRhAl+FlTOQ4L9Jka1qI4ASWMWIyzThAi3zPXaEHbUJag/L9Se7E1ZXU1WZxnebw== X-Received: by 2002:a62:f250:: with SMTP id y16mr18986778pfl.50.1564097069529; Thu, 25 Jul 2019 16:24:29 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:28 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:05 -0700 Message-Id: <1564097054-72663-4-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 03/12] ovs-vsctl: Add datapath and CT zone commands. 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 From: William Tu The patch adds the following commands $ ovs-vsctl {add,del,list}-dp for creating/deleting/listing the datapath, and $ ovs-vsctl {add,del,list}-zone-tp for conntrack zones and timeout policies. Signed-off-by: William Tu --- tests/ovs-vsctl.at | 20 +++- utilities/ovs-vsctl.8.in | 29 ++++++ utilities/ovs-vsctl.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 292 insertions(+), 2 deletions(-) diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at index 77604c58a2bc..8854138ecb1e 100644 --- a/tests/ovs-vsctl.at +++ b/tests/ovs-vsctl.at @@ -805,6 +805,22 @@ AT_CHECK( [RUN_OVS_VSCTL([--if-exists remove netflow x targets '"1.2.3.4:567"'])]) AT_CHECK( [RUN_OVS_VSCTL([--if-exists clear netflow x targets])]) + +AT_CHECK([RUN_OVS_VSCTL([add-dp netdev])]) +AT_CHECK([RUN_OVS_VSCTL([add-dp system])]) +AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=1 icmp_first=1 icmp_reply=2])]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:1, Timeout Policies: icmp_first=1 icmp_reply=2 +]) +AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:1, Timeout Policies: icmp_first=1 icmp_reply=2 +Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 +]) +AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=1])]) +AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 +]) +AT_CHECK([RUN_OVS_VSCTL([del-dp netdev])]) +AT_CHECK([RUN_OVS_VSCTL([list-dp | sed 's/ uuid.*$//'])], [0], [system +]) OVS_VSCTL_CLEANUP AT_CLEANUP @@ -890,10 +906,10 @@ AT_CHECK([RUN_OVS_VSCTL([set bridge br0 flood_vlans=-1])], AT_CHECK([RUN_OVS_VSCTL([set bridge br0 flood_vlans=4096])], [1], [], [ovs-vsctl: constraint violation: 4096 is not in the valid range 0 to 4095 (inclusive) ]) -AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], +AT_CHECK([RUN_OVS_VSCTL([set controller br1 'connection-mode=xyz'])], [1], [], [[ovs-vsctl: constraint violation: xyz is not one of the allowed values ([in-band, out-of-band]) ]]) -AT_CHECK([RUN_OVS_VSCTL([set c br1 connection-mode:x=y])], +AT_CHECK([RUN_OVS_VSCTL([set controller br1 connection-mode:x=y])], [1], [], [ovs-vsctl: cannot specify key to set for non-map column connection_mode ]) AT_CHECK([RUN_OVS_VSCTL([add bridge br1 datapath_id x y])], diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in index 7c09df79bd29..f8ec995247e7 100644 --- a/utilities/ovs-vsctl.8.in +++ b/utilities/ovs-vsctl.8.in @@ -353,6 +353,35 @@ list. Prints the name of the bridge that contains \fIiface\fR on standard output. . +.SS "Datapath Commands" +These commands examine and manipulate Open vSwitch datapath. +. +.IP "\fBadd\-dp \fIdatapath\fR" +Creates a new datapath named \fIdatapath\fR. Use "netdev" for userspace +datapath and "system" for kernel datapath. Initially the datapath will +have no CT zones or other data. +.IP "\fBdel\-dp \fIdatapath\fR" +Deletes \fIdatapath\fR. +.IP "\fBlist\-dp \fIdatapath\fR" +Prints the datapath name and its uuid. +. +.SS "Conntrack Zone Commands" +These commands query and modify datapath CT zones and Timeout Policies. +. +.IP "\fBadd\-zone\-tp \fIdatapath \fBzone=\fIzone_id \fIpolicies\fR" +Creates a conntrack zone with \fIzone_id\fR under the datapath \fIdatapath\fR. +Associate the conntrack timeout policies to it by a list of +\fIkey\fB=\fIvalue\fR pairs, separated by space. For example, specifying +30-second timeout policy for first icmp packet, and 60-second for icmp reply packet +by doing \fBicmp_first=30 icmp_reply=60\fR. See CT_Timeout_Policy TABLE +at \fBovs-vswitchd.conf.db\fR(5) for all available configurations. +. +.IP "\fBdel\-zone\-tp \fIdatapath \fBzone=\fIzone_id\fR" +Delete a zone under \fIdatapath\fR by specifying its zone ID. +. +.IP "\fBlist\-zone\-tp \fIdatapath\fR" +Prints the timeout policies of all zones under the \fIdatapath\fR. +. .SS "OpenFlow Controller Connectivity" . \fBovs\-vswitchd\fR can perform all configured bridging and switching diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index 4948137efe8c..3ec9b2b05f35 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -40,6 +40,7 @@ #include "ovsdb-idl.h" #include "openvswitch/poll-loop.h" #include "process.h" +#include "simap.h" #include "stream.h" #include "stream-ssl.h" #include "smap.h" @@ -49,6 +50,7 @@ #include "table.h" #include "timeval.h" #include "util.h" +#include "openvswitch/ofp-parse.h" #include "openvswitch/vconn.h" #include "openvswitch/vlog.h" @@ -1154,6 +1156,239 @@ cmd_emer_reset(struct ctl_context *ctx) } static void +cmd_add_dp(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs; + struct ovsrec_datapath *dp; + const char *dp_name; + int i; + + dp_name = ctx->argv[1]; + + for (i = 0; i < ovs->n_datapaths; i++) { + if (!strcmp(dp_name, ovs->key_datapaths[i])) { + VLOG_ERR("Datapath %s alread exists", dp_name); + return; + } + } + + dp = ovsrec_datapath_insert(ctx->txn); + ovsrec_open_vswitch_update_datapaths_setkey(ovs, dp_name, dp); +} + +static void +cmd_del_dp(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs; + + ovsrec_open_vswitch_update_datapaths_delkey(ovs, ctx->argv[1]); +} + +static void +cmd_list_dp(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs; + int i; + + for (i = 0; i < ovs->n_datapaths; i++) { + struct ovsrec_datapath *dp = ovs->value_datapaths[i]; + char *key; + + key = ovs->key_datapaths[i]; + ds_put_format(&ctx->output, "%s uuid="UUID_FMT"\n", + key, UUID_ARGS(&dp->header_.uuid)); + } +} + +static void +pre_get_dp(struct ctl_context *ctx) +{ + ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_datapaths); +} + +static struct ovsrec_datapath * +find_datapath(struct vsctl_context *vsctl_ctx, const char *dp_name) +{ + const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs; + int i; + + for (i = 0; i < ovs->n_datapaths; i++) { + if (!strcmp(ovs->key_datapaths[i], dp_name)) { + return ovs->value_datapaths[i]; + } + } + return NULL; +} + +static struct ovsrec_ct_zone * +find_ct_zone(struct ovsrec_datapath *dp, const int64_t zone_id) +{ + int i; + + for (i = 0; i < dp->n_ct_zones; i++) { + if (dp->key_ct_zones[i] == zone_id) { + return dp->value_ct_zones[i]; + } + } + return NULL; +} + +static struct ovsrec_ct_timeout_policy * +create_timeout_policy(struct ctl_context *ctx, char **argv, int n_tps) +{ + const struct ovsrec_ct_timeout_policy_table *tp_table; + const struct ovsrec_ct_timeout_policy *row; + struct ovsrec_ct_timeout_policy *tp = NULL; + const char **key_timeouts; + int64_t *value_timeouts; + struct simap new_tp, s; + uint32_t hash_new_tp; + int i, j; + + simap_init(&new_tp); + + key_timeouts = xmalloc(sizeof *key_timeouts * n_tps); + value_timeouts = xmalloc(sizeof *value_timeouts * n_tps); + + /* Parse timeout arguments. */ + for (i = 0; i < n_tps; i++) { + char *key, *value, *pos, *copy; + + pos = copy = xstrdup(argv[i]); + if (!ofputil_parse_key_value(&pos, &key, &value)) { + goto done; + } + key_timeouts[i] = key; + value_timeouts[i] = atoi(value); + simap_put(&new_tp, key, (unsigned int)value_timeouts[i]); + } +done: + hash_new_tp = simap_hash(&new_tp); + + tp_table = ovsrec_ct_timeout_policy_table_get(ctx->idl); + OVSREC_CT_TIMEOUT_POLICY_TABLE_FOR_EACH (row, tp_table) { + simap_init(&s); + /* Covert to simap. */ + for (j = 0; j < row->n_timeouts; j++) { + simap_put(&s, row->key_timeouts[j], row->value_timeouts[j]); + } + if (simap_hash(&s) == hash_new_tp) { + tp = CONST_CAST(struct ovsrec_ct_timeout_policy *, row); + simap_destroy(&s); + break; + } + simap_destroy(&s); + } + + if (!tp) { + tp = ovsrec_ct_timeout_policy_insert(ctx->txn); + ovsrec_ct_timeout_policy_set_timeouts(tp, key_timeouts, + (const int64_t *)value_timeouts, + n_tps); + } + + free(key_timeouts); + free(value_timeouts); + return tp; +} + +static void +cmd_add_zone(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + struct ovsrec_ct_timeout_policy *tp; + struct ovsrec_ct_zone *zone; + struct ovsrec_datapath *dp; + const char *dp_name; + int64_t zone_id; + int n_tps; + + dp_name = ctx->argv[1]; + ovs_scan(ctx->argv[2], "zone=%"SCNi64, &zone_id); + + dp = find_datapath(vsctl_ctx, dp_name); + if (!dp) { + VLOG_ERR("datapath: %s record not found", dp_name); + return; + } + + n_tps = ctx->argc - 3; + tp = create_timeout_policy(ctx, &ctx->argv[3], n_tps); + + zone = find_ct_zone(dp, zone_id); + if (zone) { + ovsrec_ct_zone_set_timeout_policy(zone, tp); + } else { + zone = ovsrec_ct_zone_insert(ctx->txn); + ovsrec_ct_zone_set_timeout_policy(zone, tp); + ovsrec_datapath_update_ct_zones_setkey(dp, zone_id, zone); + } +} + +static void +cmd_del_zone(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + struct ovsrec_datapath *dp; + const char *dp_name; + int64_t zone_id; + + dp_name = ctx->argv[1]; + ovs_scan(ctx->argv[2], "zone=%"SCNi64, &zone_id); + + dp = find_datapath(vsctl_ctx, dp_name); + if (!dp) { + VLOG_ERR("datapath: %s record not found", dp_name); + return; + } + + ovsrec_datapath_update_ct_zones_delkey(dp, zone_id); +} + +static void +cmd_list_zone(struct ctl_context *ctx) +{ + struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); + struct ovsrec_ct_timeout_policy *tp; + struct ovsrec_ct_zone *zone; + struct ovsrec_datapath *dp; + int i, j; + + dp = find_datapath(vsctl_ctx, ctx->argv[1]); + if (!dp) { + VLOG_ERR("datapath: %s record not found", ctx->argv[1]); + return; + } + + for (i = 0; i < dp->n_ct_zones; i++) { + zone = dp->value_ct_zones[i]; + ds_put_format(&ctx->output, "Zone:%"PRIu64", Timeout Policies: ", + dp->key_ct_zones[i]); + + tp = zone->timeout_policy; + + for (j = 0; j < tp->n_timeouts - 1; j++) { + ds_put_format(&ctx->output, "%s=%"PRIu64" ", + tp->key_timeouts[j], tp->value_timeouts[j]); + } + ds_put_format(&ctx->output, "%s=%"PRIu64"\n", + tp->key_timeouts[j], tp->value_timeouts[j]); + } +} + +static void +pre_get_zone(struct ctl_context *ctx) +{ + ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_datapaths); + ovsdb_idl_add_column(ctx->idl, &ovsrec_datapath_col_ct_zones); + ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_zone_col_timeout_policy); + ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_timeout_policy_col_timeouts); +} + +static void cmd_add_br(struct ctl_context *ctx) { struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx); @@ -2896,6 +3131,16 @@ static const struct ctl_command_syntax vsctl_commands[] = { /* Switch commands. */ {"emer-reset", 0, 0, "", pre_cmd_emer_reset, cmd_emer_reset, NULL, "", RW}, + /* Datapath commands. */ + {"add-dp", 1, 1, "", pre_get_dp, cmd_add_dp, NULL, "", RW}, + {"del-dp", 1, 1, "", pre_get_dp, cmd_del_dp, NULL, "", RW}, + {"list-dp", 0, 0, "", pre_get_dp, cmd_list_dp, NULL, "", RO}, + + /* Zone and CT Timeout Policy commands. */ + {"add-zone-tp", 2, 19, "", pre_get_zone, cmd_add_zone, NULL, "", RW}, + {"del-zone-tp", 2, 2, "", pre_get_zone, cmd_del_zone, NULL, "", RW}, + {"list-zone-tp", 1, 1, "", pre_get_zone, cmd_list_zone, NULL, "", RO}, + {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO}, }; From patchwork Thu Jul 25 23:24:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137162 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="F2wxXJEU"; 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 45vpJd5mSnz9s4Y for ; Fri, 26 Jul 2019 09:26:57 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A66ABC9A; Thu, 25 Jul 2019 23:24:34 +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 35898CAA for ; Thu, 25 Jul 2019 23:24:32 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id E55BCB0 for ; Thu, 25 Jul 2019 23:24:31 +0000 (UTC) Received: by mail-pf1-f173.google.com with SMTP id m30so23514572pff.8 for ; Thu, 25 Jul 2019 16:24:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CLvRfEJLK+R/d2A5MjDQFGy38dq5RtREraKsTjaKB34=; b=F2wxXJEUD482rlsgSUtxzauBXmEWhcDd21UtqBjJfAlzCVlKkSG5tKePXtRmnFG6R3 NZSlechtBiP/I8YDT3VZ4confDZfeYzkdMP1gnvJInn7w0jyie0eMaz0HqkpOsVhTpya Jzn1p8SYedrI+AhO34F52zNObFt9GU+4abYhT/MmCp+fuyRm08c6tPQ6qIt2D2vLpQhh 9Be/TYKv9n0515TS6GEv/R6WQ5dVSsXvJr2W2aiPqOihYzeKLNCFbIb4Gdk/S90AGEU1 ac68vvsgUCSsUBrDBzzsAWnR82RpJl4690+WetGeb6xuRVIgllUo2XSjHn9WFMZ6z3cc xHKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CLvRfEJLK+R/d2A5MjDQFGy38dq5RtREraKsTjaKB34=; b=Sqzao7lT0IyBR1cX/jJbucXXGtL00kvd78lKn4zOSEFchmor+ZLBEAT0G/8STL1/hp UAczf3YTTES5kkpXCusRHRe8ZegIfxIRe437SLZKvPKpNoL8n3IbwfbSg14g7BLEIi6R 3ggXWY7RK4WkXO6BMm+tqO2a0wm0SzWDLOZVl7S9ChG8E/Y2Iqgyk1WrINsmNzmUAhAN jgKT0XGzA8EqiT5NGfG51WRd5BCcUrAgo8fuwrYnxAZafKD0HIwZz1h2YM+jEmL7z0jV vWL4ezz4KI5fKAyuTiTFGLRV0MAfLKbURj063zH7LEIGztbNITlMAqlTZVejCYsjJXxW bh2w== X-Gm-Message-State: APjAAAXId71ZBy7tGELM2q+6hS2X/A3beXGv+PdBW/8DCmBuVjUrwN0e H+FzKuQUcelg8+qdMtZVU7RVOnGp X-Google-Smtp-Source: APXvYqzbMT9jhaVPbTeJfYNs+yL8iPQIz5F92lsW8rJy6rJ5i6MuLZtPm6rkBPJt2MjdVh+BfuPI9w== X-Received: by 2002:a62:2ccc:: with SMTP id s195mr18955086pfs.256.1564097071170; Thu, 25 Jul 2019 16:24:31 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:29 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:06 -0700 Message-Id: <1564097054-72663-5-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 04/12] ct-dpif: Export ct_dpif_format_ipproto() 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 This function will be useful for following patchs. Signed-off-by: Yi-Hung Wei --- lib/ct-dpif.c | 3 +-- lib/ct-dpif.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 5d8a75d3a63f..6ea7feb0ee35 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -31,7 +31,6 @@ struct flags { const char *name; }; -static void ct_dpif_format_ipproto(struct ds *, uint16_t ipproto); static void ct_dpif_format_counters(struct ds *, const struct ct_dpif_counters *); static void ct_dpif_format_timestamp(struct ds *, @@ -315,7 +314,7 @@ ct_dpif_format_entry(const struct ct_dpif_entry *entry, struct ds *ds, } } -static void +void ct_dpif_format_ipproto(struct ds *ds, uint16_t ipproto) { const char *name; diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 14178bb7c3f0..2f4906817946 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -250,6 +250,7 @@ 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); +void ct_dpif_format_ipproto(struct ds *ds, uint16_t ipproto); void ct_dpif_format_tuple(struct ds *, const struct ct_dpif_tuple *); uint8_t ct_dpif_coalesce_tcp_state(uint8_t state); void ct_dpif_format_tcp_stat(struct ds *, int, int); From patchwork Thu Jul 25 23:24:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137164 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="dnt92vYR"; 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 45vpKG47n6z9sBZ for ; Fri, 26 Jul 2019 09:27:30 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 55516CF6; Thu, 25 Jul 2019 23:24:35 +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 1F5EEC87 for ; Thu, 25 Jul 2019 23:24:34 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 64FEF224 for ; Thu, 25 Jul 2019 23:24:33 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id t132so23771074pgb.9 for ; Thu, 25 Jul 2019 16:24:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gBuBqnaOSvrwucpBVw2s48Mjl7CcJb0cmEdYpoc1CO0=; b=dnt92vYRjY8VtC0f66unPKBDfnM07x5KRRh4o8fVojlib9afrE4LZrYjAj61zhPGSk be6rLY3qe7XDiIwbE0ome7CCwSVSJA7XAAGFRbBe8Is7ezk05xQ8ESjVaA2ZLy2BjK25 F9tQnEt2l4iHSIHUJeZxNE3TCCLm7kiJxLwLSNyPYqPLSIVB1gWrXDd4hsViVkoGWqWE vG310dZB1PkCqWFPhpRt0x8/Tu7QNuIHdmsREyqNmS8gRxZRHpx23KE4hDnMGdbNDFNJ UGbQwE8hiaklRCvfafQBMPh7InVtkroYeuHj3uP2HVz6UapmuKSVGGEEQDO9Rpu8un5k RP3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gBuBqnaOSvrwucpBVw2s48Mjl7CcJb0cmEdYpoc1CO0=; b=V6/leUxjoUDY8c5NWk0ygGABkBwtXomsFmCVZE8vM40ccO3Sk0XubjYFSjAmP01P0q OPDhp9yTVIXBGY3TS/aZqyC/J66fqdPlI73qHoZOA4eTS+Bq47vvAt7T/eXfQuVanw5R XyakIkx66Obc/2LzaXW/wNgdELZ5qD/er6ar7P0tWnJmb7T1VAFqT6W29DzTmpFIpm1v vm2ClMEUofIqyYSP5RPo1t8ftPIdy+q49edXCB3T8SDkumcfV0CgiGu/Q2Uw11VMNwh9 sgUCNHJ4CZnvBcxZ+K+T4YkVAaeaJtRzDm8fcVXlnvc3LdEF/3coA5+DQK/WsSgfJDvP NmqA== X-Gm-Message-State: APjAAAXL7HREO/N8I49RWdXIviU2GXCpSIXEAY9ZBhDkDJZjGZt54bIg A2yGtzz5YqMkPO3PXi/WO+9ur1Zu X-Google-Smtp-Source: APXvYqzQ3I5PVvKNxjTEDx7GgX1ZHJ/UxrRpRJZ/L72zDhUybbxNM0+H7wN3QdLqWfZK3asSrl0PjA== X-Received: by 2002:a17:90a:2244:: with SMTP id c62mr97267317pje.29.1564097072494; Thu, 25 Jul 2019 16:24:32 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:31 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:07 -0700 Message-Id: <1564097054-72663-6-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 05/12] ct-dpif: Add conntrack timeout policy support in dpif layer 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 This patch defines the dpif interface for a datapath to support adding, deleting, getting and dumping conntrack timeout policy. The timeout policy is identified by a 4 bytes unsigned integer in datapath, and it currently support timeout for TCP, UDP, and ICMP protocols. Signed-off-by: Yi-Hung Wei --- lib/ct-dpif.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ct-dpif.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/dpif-netdev.c | 6 ++++++ lib/dpif-netlink.c | 6 ++++++ lib/dpif-provider.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+) diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 6ea7feb0ee35..ae347a9bb46d 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -760,3 +760,54 @@ ct_dpif_format_zone_limits(uint32_t default_limit, ds_put_format(ds, ",count=%"PRIu32, zone_limit->count); } } + +int +ct_dpif_add_timeout_policy(struct dpif *dpif, bool is_default, + const struct ct_dpif_timeout_policy *tp) +{ + return (dpif->dpif_class->ct_add_timeout_policy + ? dpif->dpif_class->ct_add_timeout_policy(dpif, is_default, tp) + : EOPNOTSUPP); +} + +int +ct_dpif_del_timeout_policy(struct dpif *dpif, uint32_t tp_id) +{ + return (dpif->dpif_class->ct_del_timeout_policy + ? dpif->dpif_class->ct_del_timeout_policy(dpif, tp_id) + : EOPNOTSUPP); +} + +int +ct_dpif_get_timeout_policy(struct dpif *dpif, bool is_default, uint32_t tp_id, + struct ct_dpif_timeout_policy *tp) +{ + return (dpif->dpif_class->ct_get_timeout_policy + ? dpif->dpif_class->ct_get_timeout_policy( + dpif, is_default, tp_id, tp) : EOPNOTSUPP); +} + +int +ct_dpif_timeout_policy_dump_start(struct dpif *dpif, void **statep) +{ + return (dpif->dpif_class->ct_timeout_policy_dump_start + ? dpif->dpif_class->ct_timeout_policy_dump_start(dpif, statep) + : EOPNOTSUPP); +} + +int +ct_dpif_timeout_policy_dump_next(struct dpif *dpif, void *state, + struct ct_dpif_timeout_policy **tp) +{ + return (dpif->dpif_class->ct_timeout_policy_dump_next + ? dpif->dpif_class->ct_timeout_policy_dump_next(dpif, state, tp) + : EOPNOTSUPP); +} + +int +ct_dpif_timeout_policy_dump_done(struct dpif *dpif, void *state) +{ + return (dpif->dpif_class->ct_timeout_policy_dump_done + ? dpif->dpif_class->ct_timeout_policy_dump_done(dpif, state) + : EOPNOTSUPP); +} diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 2f4906817946..9dc33bede527 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -225,6 +225,49 @@ struct ct_dpif_zone_limit { struct ovs_list node; }; +#define CT_DPIF_TP_TCP_ATTRS \ + CT_DPIF_TP_TCP_ATTR(SYN_SENT) \ + CT_DPIF_TP_TCP_ATTR(SYN_RECV) \ + CT_DPIF_TP_TCP_ATTR(ESTABLISHED) \ + CT_DPIF_TP_TCP_ATTR(FIN_WAIT) \ + CT_DPIF_TP_TCP_ATTR(CLOSE_WAIT) \ + CT_DPIF_TP_TCP_ATTR(LAST_ACK) \ + CT_DPIF_TP_TCP_ATTR(TIME_WAIT) \ + CT_DPIF_TP_TCP_ATTR(CLOSE) \ + CT_DPIF_TP_TCP_ATTR(SYN_SENT2) \ + CT_DPIF_TP_TCP_ATTR(RETRANSMIT) \ + CT_DPIF_TP_TCP_ATTR(UNACK) + +#define CT_DPIF_TP_UDP_ATTRS \ + CT_DPIF_TP_UDP_ATTR(FIRST) \ + CT_DPIF_TP_UDP_ATTR(SINGLE) \ + CT_DPIF_TP_UDP_ATTR(MULTIPLE) + +#define CT_DPIF_TP_ICMP_ATTRS \ + CT_DPIF_TP_ICMP_ATTR(FIRST) \ + CT_DPIF_TP_ICMP_ATTR(REPLY) + +enum OVS_PACKED_ENUM ct_dpif_tp_attr { +#define CT_DPIF_TP_TCP_ATTR(ATTR) CT_DPIF_TP_ATTR_TCP_##ATTR, + CT_DPIF_TP_TCP_ATTRS +#undef CT_DPIF_TP_TCP_ATTR +#define CT_DPIF_TP_UDP_ATTR(ATTR) CT_DPIF_TP_ATTR_UDP_##ATTR, + CT_DPIF_TP_UDP_ATTRS +#undef CT_DPIF_TP_UDP_ATTR +#define CT_DPIF_TP_ICMP_ATTR(ATTR) CT_DPIF_TP_ATTR_ICMP_##ATTR, + CT_DPIF_TP_ICMP_ATTRS +#undef CT_DPIF_TP_ICMP_ATTR + CT_DPIF_TP_ATTR_MAX +}; + +struct ct_dpif_timeout_policy { + uint32_t id; /* id that uniquely identify a timeout policy. */ + uint32_t present; /* If a timeout attribute is present set the + * corresponding bit. */ + uint32_t attrs[CT_DPIF_TP_ATTR_MAX]; /* An array that specifies + * timeout attribute values */ +}; + int ct_dpif_dump_start(struct dpif *, struct ct_dpif_dump_state **, const uint16_t *zone, int *); int ct_dpif_dump_next(struct ct_dpif_dump_state *, struct ct_dpif_entry *); @@ -262,5 +305,15 @@ bool ct_dpif_parse_zone_limit_tuple(const char *s, uint16_t *pzone, uint32_t *plimit, struct ds *); void ct_dpif_format_zone_limits(uint32_t default_limit, const struct ovs_list *, struct ds *); +int ct_dpif_add_timeout_policy(struct dpif *dpif, bool is_default, + const struct ct_dpif_timeout_policy *tp); +int ct_dpif_get_timeout_policy(struct dpif *dpif, bool is_default, + uint32_t tp_id, + struct ct_dpif_timeout_policy *tp); +int ct_dpif_del_timeout_policy(struct dpif *dpif, uint32_t tp_id); +int ct_dpif_timeout_policy_dump_start(struct dpif *dpif, void **statep); +int ct_dpif_timeout_policy_dump_next(struct dpif *dpif, void *state, + struct ct_dpif_timeout_policy **tp); +int ct_dpif_timeout_policy_dump_done(struct dpif *dpif, void *state); #endif /* CT_DPIF_H */ diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index d0a1c58adace..2079e368fb52 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7529,6 +7529,12 @@ const struct dpif_class dpif_netdev_class = { NULL, /* ct_set_limits */ NULL, /* ct_get_limits */ NULL, /* ct_del_limits */ + NULL, /* ct_set_timeout_policy */ + NULL, /* ct_get_timeout_policy */ + NULL, /* ct_del_timeout_policy */ + NULL, /* ct_timeout_policy_dump_start */ + NULL, /* ct_timeout_policy_dump_next */ + NULL, /* ct_timeout_policy_dump_done */ dpif_netdev_ipf_set_enabled, dpif_netdev_ipf_set_min_frag, dpif_netdev_ipf_set_max_nfrags, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 985a284267f5..9825ce46a7f5 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -3434,6 +3434,12 @@ const struct dpif_class dpif_netlink_class = { dpif_netlink_ct_set_limits, dpif_netlink_ct_get_limits, dpif_netlink_ct_del_limits, + NULL, /* ct_set_timeout_policy */ + NULL, /* ct_get_timeout_policy */ + NULL, /* ct_del_timeout_policy */ + NULL, /* ct_timeout_policy_dump_start */ + NULL, /* ct_timeout_policy_dump_next */ + NULL, /* ct_timeout_policy_dump_done */ NULL, /* ipf_set_enabled */ NULL, /* ipf_set_min_frag */ NULL, /* ipf_set_max_nfrags */ diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 12898b9e3c6d..3460ef8aa98d 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -80,6 +80,7 @@ dpif_flow_dump_thread_init(struct dpif_flow_dump_thread *thread, struct ct_dpif_dump_state; struct ct_dpif_entry; struct ct_dpif_tuple; +struct ct_dpif_timeout_policy; /* 'dpif_ipf_proto_status' and 'dpif_ipf_status' are presently in * sync with 'ipf_proto_status' and 'ipf_status', but more @@ -498,6 +499,48 @@ struct dpif_class { * list of 'struct ct_dpif_zone_limit' entries. */ int (*ct_del_limits)(struct dpif *, const struct ovs_list *zone_limits); + /* Connection tracking timeout policy */ + + /* A connection tracking timeout policy contains a list of timeout + * attributes that specifies timeout values on various connection states. + * In a datapath, the timeout policy is identified by a 4 bytes unsigned + * integer, and the unsupported timeout attributes are ignored. + * When a connection is committed it can be associated with a timeout + * policy, or it defaults to the default timeout policy. */ + + /* Add timeout policy '*tp' into the datapath. If 'is_default' is true + * make the timeout policy to be the default timeout policy. */ + int (*ct_add_timeout_policy)(struct dpif *, bool is_default, + const struct ct_dpif_timeout_policy *tp); + /* Gets a timeout policy and stores that into '*tp'. If 'is_default' is + * true, sets '*tp' to the default timeout policy. Otherwise, gets the + * timeout policy by 'tp_id'. */ + int (*ct_get_timeout_policy)(struct dpif *, bool is_default, + uint32_t tp_id, + struct ct_dpif_timeout_policy *tp); + /* Deletes a timeout policy identified by 'tp_id'. */ + int (*ct_del_timeout_policy)(struct dpif *, uint32_t tp_id); + + /* Conntrack timeout policy dumping interface. + * + * These functions provide a datapath-agnostic dumping interface + * to the conntrack timeout policy provided by the datapaths. + * + * ct_timeout_policy_dump_start() should put in '*statep' a pointer to + * a newly allocated structure that will be passed by the caller to + * ct_timeout_policy_dump_next() and ct_timeout_policy_dump_done(). + * + * ct_timeout_policy_dump_next() fills a timeout policy pointed by + * '*tp' and prepares to dump the next one on a subsequent invocation. + * The caller is responsible to free '*tp'. + * + * ct_timeout_policy_dump_done() should perform any cleanup necessary + * (including deallocating the 'state' structure, if applicable). */ + int (*ct_timeout_policy_dump_start)(struct dpif *, void **statep); + int (*ct_timeout_policy_dump_next)(struct dpif *, void *state, + struct ct_dpif_timeout_policy **tp); + int (*ct_timeout_policy_dump_done)(struct dpif *, void *state); + /* IP Fragmentation. */ /* Disables or enables conntrack fragment reassembly. The default From patchwork Thu Jul 25 23:24:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137165 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="l0B4kbG0"; 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 45vpKz4Prqz9s4Y for ; Fri, 26 Jul 2019 09:28:07 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4D425D30; Thu, 25 Jul 2019 23:24:37 +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 70AE3D1A for ; Thu, 25 Jul 2019 23:24:35 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 19A8C224 for ; Thu, 25 Jul 2019 23:24:35 +0000 (UTC) Received: by mail-pf1-f196.google.com with SMTP id y15so23506484pfn.5 for ; Thu, 25 Jul 2019 16:24:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=w+2MckYxoqq2iiw9mp+nUczzZDSaFunEJa2qVE3KX3g=; b=l0B4kbG0eCVEV7IJyjrx6yQn6JQ5WRSzH4qNRsBfWB2qghmfdmXzDF2ufypvX8Tegz IXH1Q2eVrGNpxP174LD/0ie07KHjsUhYm5sgEghxYxh+Ue8/25MpNm2GiaEMy6U21g+h EpcMh8ct947mvzqdt2bYrDa91JC/hBPmNGf1LMrIwk7q1sazNAIKIpAFnm61dto11j6f 8vzfgmSxNPKDDYuhr9NlAjK99QoW4f26Iq6/fAXhQmSwo7OXdM5uv7K4rxquJGlhQvXR fGnFyKDJl0gdzS0m2cxvJatWa0Jg+nI6jGkDFhVVgBPiEHUOh7XokC1ZyCI3DwgihjJh 2nhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=w+2MckYxoqq2iiw9mp+nUczzZDSaFunEJa2qVE3KX3g=; b=ukijzMbwF8sCZE/is89+h4aY++VUwB9J5/eF0Gr4PT6u0pXl7SA7HI5LcLROa4mgEv ylv1PrCwkQmgWMtM949m0QFCoX++Rb6WEzUX+XZO/p29y6r+gBGHMo9FYOOXWh8bRBWc pWXUpiV74CtelPWN6AzLN0QkeOLXsEP8WCmgnaSzn6tvlGwsadwckXqa5UAZWVxNdSc/ 5e8F9QtK9/T1BEI1TnOFcxhy90QwPqrzbnoi/sSX8OjUQYoDyOjo++OMl5qzFXkipkL0 HraoZ58A2PW4YglFWRrmPJvEsiCof7mZOlKTVYKZ58P3tbmBgSYrprVJOFzOiSZY5HlG 4GKQ== X-Gm-Message-State: APjAAAVYv3He/aj+W+At2P5q4Nq6rndYde+SXJQhPk+WwMhscRG6JUm4 GpCso//sKhq8eyR28Xpi170GP64u X-Google-Smtp-Source: APXvYqw4pnpXTUBr0sXmhix+XQHwcQaO+iTdeBad+1ZHnUbQTGatwqGem3pA+6xok7kUgCzZb2fRoA== X-Received: by 2002:a63:5811:: with SMTP id m17mr17939716pgb.237.1564097074089; Thu, 25 Jul 2019 16:24:34 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:32 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:08 -0700 Message-Id: <1564097054-72663-7-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 06/12] ct-dpif: Add timeout policy related utility functions. 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 These functions will be useful in the following patches. Signed-off-by: Yi-Hung Wei Acked-by: William Tu --- lib/ct-dpif.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ct-dpif.h | 3 +++ 2 files changed, 56 insertions(+) diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index ae347a9bb46d..1625754e2441 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -761,6 +761,59 @@ ct_dpif_format_zone_limits(uint32_t default_limit, } } +static const char *const ct_dpif_tp_attr_string[] = { +#define CT_DPIF_TP_TCP_ATTR(ATTR) \ + [CT_DPIF_TP_ATTR_TCP_##ATTR] = "TCP_"#ATTR, + CT_DPIF_TP_TCP_ATTRS +#undef CT_DPIF_TP_TCP_ATTR +#define CT_DPIF_TP_UDP_ATTR(ATTR) \ + [CT_DPIF_TP_ATTR_UDP_##ATTR] = "UDP_"#ATTR, + CT_DPIF_TP_UDP_ATTRS +#undef CT_DPIF_TP_UDP_ATTR +#define CT_DPIF_TP_ICMP_ATTR(ATTR) \ + [CT_DPIF_TP_ATTR_ICMP_##ATTR] = "ICMP_"#ATTR, + CT_DPIF_TP_ICMP_ATTRS +#undef CT_DPIF_TP_ICMP_ATTR +}; + +static bool +ct_dpif_set_timeout_policy_attr(struct ct_dpif_timeout_policy *tp, + uint32_t attr, uint32_t value) +{ + if (tp->present & (1 << attr) && tp->attrs[attr] == value) { + return false; + } + tp->attrs[attr] = value; + tp->present |= 1 << attr; + return true; +} + +/* Sets a timeout value identified by '*name' to 'value'. + * Returns true if the attribute is changed */ +bool +ct_dpif_set_timeout_policy_attr_by_name(struct ct_dpif_timeout_policy *tp, + const char *name, uint32_t value) +{ + uint32_t i; + + for (i = 0; i < CT_DPIF_TP_ATTR_MAX; ++i) { + if (!strcasecmp(name, ct_dpif_tp_attr_string[i])) { + return ct_dpif_set_timeout_policy_attr(tp, i, value); + } + } + return false; +} + +bool +ct_dpif_timeout_policy_support_ipproto(uint8_t ipproto) +{ + if (ipproto == IPPROTO_TCP || ipproto == IPPROTO_UDP || + ipproto == IPPROTO_ICMP || ipproto == IPPROTO_ICMPV6) { + return true; + } + return false; +} + int ct_dpif_add_timeout_policy(struct dpif *dpif, bool is_default, const struct ct_dpif_timeout_policy *tp) diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 9dc33bede527..de032cc416ce 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -305,6 +305,9 @@ bool ct_dpif_parse_zone_limit_tuple(const char *s, uint16_t *pzone, uint32_t *plimit, struct ds *); void ct_dpif_format_zone_limits(uint32_t default_limit, const struct ovs_list *, struct ds *); +bool ct_dpif_set_timeout_policy_attr_by_name(struct ct_dpif_timeout_policy *tp, + const char *key, uint32_t value); +bool ct_dpif_timeout_policy_support_ipproto(uint8_t ipproto); int ct_dpif_add_timeout_policy(struct dpif *dpif, bool is_default, const struct ct_dpif_timeout_policy *tp); int ct_dpif_get_timeout_policy(struct dpif *dpif, bool is_default, From patchwork Thu Jul 25 23:24:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137166 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="XWFePvBH"; 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 45vpLY0nlcz9sBF for ; Fri, 26 Jul 2019 09:28:37 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id EF43AD38; Thu, 25 Jul 2019 23:24:39 +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 1491DCAE for ; Thu, 25 Jul 2019 23:24:39 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com [209.85.215.171]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1B64DB0 for ; Thu, 25 Jul 2019 23:24:37 +0000 (UTC) Received: by mail-pg1-f171.google.com with SMTP id i18so23781669pgl.11 for ; Thu, 25 Jul 2019 16:24:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZN86ifkhaU0wTKL/DWeHHMgipjQXTSHZODc0GRMe45w=; b=XWFePvBH+I30+pcI+cbgrYSnvN6XTEWxRLcT9RVONSLEsG8sE5NjBJtP+laNjXFpER 7HKFvrFz6bhnEXtPjnAvAxIB179x2g2Pl4EZSzj6PPQuxVecskZPeMhNawIPdPqBQ9Kq DGG5xCcWXTC+sesvksExXpLTC0JDqHFDU2u3MBOS0XCITmlpCqqdisPh3wEBBkaINAHe FsU6j1M1bXwaViBTskM+J2xBDJuxoli+eIrayFuEN8uqNrA9j8ft+jdhFQZhFSFFAens 0E5l2wZV1CkmCnVSi/Rz+30K1it0fODMcm1C6gntJhnfKNV4SUkYPGujme5VuJZH7TuI f3Iw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZN86ifkhaU0wTKL/DWeHHMgipjQXTSHZODc0GRMe45w=; b=Xc9dvW4T55XB7Y9wME8X7HgGDfdDXwkQQKE2dIL37vGHvWGSZRryM1UVoe01lcFtpW 7voQbKDpaVV01mDO+cjcmWEaQKen4RwLRJ+Vsu30bEHRrZKU257rAClbh8KCy204tEnS A3SIMf8FeO6P7zpvhyTaoaEDXzWG8gj/rJspBnFfTs3N6dAEiUlGqp/icvqrYrgVFknr WpKO3GXwxsuRFXyi1OlB6XGsJtWkqyi3gqrMy2Hcsmk+cDuvcvuskzR9DgSDgp9tVbu2 VgwmqzUlscxC2ruxPId1NCY3wVDDO88WRibQeO9pAMYqfg4rHyzVu1IZXDN7gaEo4m2p JBmA== X-Gm-Message-State: APjAAAUKMuPNe8+OYkcH+f0krWsuu77OPHIvXKiaAQxLTj+S34uuXZ0K 1vkG3fJRc36opWvQZ8ZH4fpurjHb X-Google-Smtp-Source: APXvYqyghWn/k7fUeOG888KIqAhsM51DxkxXrKG0sALu3a/DN8KUuMLqmuENERxPmAdAZCEsrDNCyQ== X-Received: by 2002:a17:90a:2163:: with SMTP id a90mr90557810pje.3.1564097075741; Thu, 25 Jul 2019 16:24:35 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:34 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:09 -0700 Message-Id: <1564097054-72663-8-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 07/12] dpif-netlink: Add conntrack timeout policy support 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 This patch implements all the conntrack timeout policy related functions defined in dpif_class for dpif-netlink class in Linux kernel datapath. In Linux kernel, the timeout policy is maintained per L3/L4 protocol, and it is identified by 32 bytes null terminated string. However, in vswitchd, the timeout policy is a generic one that consists of all the supported L4 protocols. Therefore, the main task for this patch is to break down the generic timeout policy into 6 sub policies ( ipv4 tcp, udp, icmp, and ipv6 tcp, udp, icmp) in dpif-netlink.c and push down the configuration using the netlink API in netlink-conntrack.c. This patch also adds missing symbols in the windows datapath so that the build on windows can pass. Appveyor CI: * https://ci.appveyor.com/project/YiHungWei/ovs/builds/26250549 Signed-off-by: Yi-Hung Wei --- datapath-windows/include/OvsDpInterfaceCtExt.h | 114 ++++++ datapath-windows/ovsext/Netlink/NetlinkProto.h | 1 + include/windows/automake.mk | 1 + .../windows/linux/netfilter/nfnetlink_cttimeout.h | 0 lib/dpif-netlink.c | 432 ++++++++++++++++++++- lib/dpif-netlink.h | 2 +- lib/netlink-conntrack.c | 363 +++++++++++++++++ lib/netlink-conntrack.h | 29 ++ lib/netlink-protocol.h | 1 + 9 files changed, 936 insertions(+), 7 deletions(-) create mode 100644 include/windows/linux/netfilter/nfnetlink_cttimeout.h diff --git a/datapath-windows/include/OvsDpInterfaceCtExt.h b/datapath-windows/include/OvsDpInterfaceCtExt.h index 3b947782e90c..4379855bb8dd 100644 --- a/datapath-windows/include/OvsDpInterfaceCtExt.h +++ b/datapath-windows/include/OvsDpInterfaceCtExt.h @@ -421,4 +421,118 @@ struct nf_ct_tcp_flags { UINT8 mask; }; +/* File: nfnetlink_cttimeout.h */ +enum ctnl_timeout_msg_types { + IPCTNL_MSG_TIMEOUT_NEW, + IPCTNL_MSG_TIMEOUT_GET, + IPCTNL_MSG_TIMEOUT_DELETE, + IPCTNL_MSG_TIMEOUT_DEFAULT_SET, + IPCTNL_MSG_TIMEOUT_DEFAULT_GET, + + IPCTNL_MSG_TIMEOUT_MAX +}; + +enum ctattr_timeout { + CTA_TIMEOUT_UNSPEC, + CTA_TIMEOUT_NAME, + CTA_TIMEOUT_L3PROTO, + CTA_TIMEOUT_L4PROTO, + CTA_TIMEOUT_DATA, + CTA_TIMEOUT_USE, + __CTA_TIMEOUT_MAX +}; +#define CTA_TIMEOUT_MAX (__CTA_TIMEOUT_MAX - 1) + +enum ctattr_timeout_generic { + CTA_TIMEOUT_GENERIC_UNSPEC, + CTA_TIMEOUT_GENERIC_TIMEOUT, + __CTA_TIMEOUT_GENERIC_MAX +}; +#define CTA_TIMEOUT_GENERIC_MAX (__CTA_TIMEOUT_GENERIC_MAX - 1) + +enum ctattr_timeout_tcp { + CTA_TIMEOUT_TCP_UNSPEC, + CTA_TIMEOUT_TCP_SYN_SENT, + CTA_TIMEOUT_TCP_SYN_RECV, + CTA_TIMEOUT_TCP_ESTABLISHED, + CTA_TIMEOUT_TCP_FIN_WAIT, + CTA_TIMEOUT_TCP_CLOSE_WAIT, + CTA_TIMEOUT_TCP_LAST_ACK, + CTA_TIMEOUT_TCP_TIME_WAIT, + CTA_TIMEOUT_TCP_CLOSE, + CTA_TIMEOUT_TCP_SYN_SENT2, + CTA_TIMEOUT_TCP_RETRANS, + CTA_TIMEOUT_TCP_UNACK, + __CTA_TIMEOUT_TCP_MAX +}; +#define CTA_TIMEOUT_TCP_MAX (__CTA_TIMEOUT_TCP_MAX - 1) + +enum ctattr_timeout_udp { + CTA_TIMEOUT_UDP_UNSPEC, + CTA_TIMEOUT_UDP_UNREPLIED, + CTA_TIMEOUT_UDP_REPLIED, + __CTA_TIMEOUT_UDP_MAX +}; +#define CTA_TIMEOUT_UDP_MAX (__CTA_TIMEOUT_UDP_MAX - 1) + +enum ctattr_timeout_udplite { + CTA_TIMEOUT_UDPLITE_UNSPEC, + CTA_TIMEOUT_UDPLITE_UNREPLIED, + CTA_TIMEOUT_UDPLITE_REPLIED, + __CTA_TIMEOUT_UDPLITE_MAX +}; +#define CTA_TIMEOUT_UDPLITE_MAX (__CTA_TIMEOUT_UDPLITE_MAX - 1) + +enum ctattr_timeout_icmp { + CTA_TIMEOUT_ICMP_UNSPEC, + CTA_TIMEOUT_ICMP_TIMEOUT, + __CTA_TIMEOUT_ICMP_MAX +}; +#define CTA_TIMEOUT_ICMP_MAX (__CTA_TIMEOUT_ICMP_MAX - 1) + +enum ctattr_timeout_dccp { + CTA_TIMEOUT_DCCP_UNSPEC, + CTA_TIMEOUT_DCCP_REQUEST, + CTA_TIMEOUT_DCCP_RESPOND, + CTA_TIMEOUT_DCCP_PARTOPEN, + CTA_TIMEOUT_DCCP_OPEN, + CTA_TIMEOUT_DCCP_CLOSEREQ, + CTA_TIMEOUT_DCCP_CLOSING, + CTA_TIMEOUT_DCCP_TIMEWAIT, + __CTA_TIMEOUT_DCCP_MAX +}; +#define CTA_TIMEOUT_DCCP_MAX (__CTA_TIMEOUT_DCCP_MAX - 1) + +enum ctattr_timeout_sctp { + CTA_TIMEOUT_SCTP_UNSPEC, + CTA_TIMEOUT_SCTP_CLOSED, + CTA_TIMEOUT_SCTP_COOKIE_WAIT, + CTA_TIMEOUT_SCTP_COOKIE_ECHOED, + CTA_TIMEOUT_SCTP_ESTABLISHED, + CTA_TIMEOUT_SCTP_SHUTDOWN_SENT, + CTA_TIMEOUT_SCTP_SHUTDOWN_RECD, + CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT, + CTA_TIMEOUT_SCTP_HEARTBEAT_SENT, + CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED, + __CTA_TIMEOUT_SCTP_MAX +}; +#define CTA_TIMEOUT_SCTP_MAX (__CTA_TIMEOUT_SCTP_MAX - 1) + +enum ctattr_timeout_icmpv6 { + CTA_TIMEOUT_ICMPV6_UNSPEC, + CTA_TIMEOUT_ICMPV6_TIMEOUT, + __CTA_TIMEOUT_ICMPV6_MAX +}; +#define CTA_TIMEOUT_ICMPV6_MAX (__CTA_TIMEOUT_ICMPV6_MAX - 1) + +enum ctattr_timeout_gre { + CTA_TIMEOUT_GRE_UNSPEC, + CTA_TIMEOUT_GRE_UNREPLIED, + CTA_TIMEOUT_GRE_REPLIED, + __CTA_TIMEOUT_GRE_MAX +}; +#define CTA_TIMEOUT_GRE_MAX (__CTA_TIMEOUT_GRE_MAX - 1) + +#define CTNL_TIMEOUT_NAME_MAX 32 + #endif /* __OVS_DP_INTERFACE_CT_EXT_H_ */ diff --git a/datapath-windows/ovsext/Netlink/NetlinkProto.h b/datapath-windows/ovsext/Netlink/NetlinkProto.h index 59b56565c1dc..db1fa2bacae8 100644 --- a/datapath-windows/ovsext/Netlink/NetlinkProto.h +++ b/datapath-windows/ovsext/Netlink/NetlinkProto.h @@ -51,6 +51,7 @@ #define NLM_F_ECHO 0x008 #define NLM_F_ROOT 0x100 +#define NLM_F_REPLACE 0x100 #define NLM_F_MATCH 0x200 #define NLM_F_EXCL 0x200 #define NLM_F_ATOMIC 0x400 diff --git a/include/windows/automake.mk b/include/windows/automake.mk index 382627b51787..883bbbf5d97c 100644 --- a/include/windows/automake.mk +++ b/include/windows/automake.mk @@ -15,6 +15,7 @@ noinst_HEADERS += \ include/windows/linux/netfilter/nf_conntrack_tcp.h \ include/windows/linux/netfilter/nfnetlink.h \ include/windows/linux/netfilter/nfnetlink_conntrack.h \ + include/windows/linux/netfilter/nfnetlink_cttimeout.h \ include/windows/linux/pkt_sched.h \ include/windows/linux/types.h \ include/windows/net/if.h \ diff --git a/include/windows/linux/netfilter/nfnetlink_cttimeout.h b/include/windows/linux/netfilter/nfnetlink_cttimeout.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 9825ce46a7f5..abfad9543c3b 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -50,6 +50,7 @@ #include "odp-util.h" #include "openvswitch/dynamic-string.h" #include "openvswitch/flow.h" +#include "openvswitch/hmap.h" #include "openvswitch/match.h" #include "openvswitch/ofpbuf.h" #include "openvswitch/poll-loop.h" @@ -3028,6 +3029,425 @@ dpif_netlink_ct_del_limits(struct dpif *dpif OVS_UNUSED, ofpbuf_delete(request); return err; } + +#define NL_TP_NAME_PREFIX "ovs_tp_" + +struct dpif_netlink_timeout_policy_protocol { + uint16_t l3num; + uint8_t l4num; +}; + +enum OVS_PACKED_ENUM dpif_netlink_support_timeout_policy_protocol { + DPIF_NL_TP_AF_INET_TCP, + DPIF_NL_TP_AF_INET_UDP, + DPIF_NL_TP_AF_INET_ICMP, + DPIF_NL_TP_AF_INET6_TCP, + DPIF_NL_TP_AF_INET6_UDP, + DPIF_NL_TP_AF_INET6_ICMPV6, + DPIF_NL_TP_MAX +}; + +#define DPIF_NL_ALL_TP 0x3F + +static struct dpif_netlink_timeout_policy_protocol tp_protos[] = { + [DPIF_NL_TP_AF_INET_TCP] = { .l3num = AF_INET, .l4num = IPPROTO_TCP }, + [DPIF_NL_TP_AF_INET_UDP] = { .l3num = AF_INET, .l4num = IPPROTO_UDP }, + [DPIF_NL_TP_AF_INET_ICMP] = { .l3num = AF_INET, .l4num = IPPROTO_ICMP }, + [DPIF_NL_TP_AF_INET6_TCP] = { .l3num = AF_INET6, .l4num = IPPROTO_TCP }, + [DPIF_NL_TP_AF_INET6_UDP] = { .l3num = AF_INET6, .l4num = IPPROTO_UDP }, + [DPIF_NL_TP_AF_INET6_ICMPV6] = { .l3num = AF_INET6, + .l4num = IPPROTO_ICMPV6 }, +}; + +static void +dpif_netlink_format_tp_name(uint32_t id, uint16_t l3num, uint8_t l4num, + struct ds *tp_name) +{ + ds_clear(tp_name); + ds_put_format(tp_name, "%s%"PRIu32"_", NL_TP_NAME_PREFIX, id); + ct_dpif_format_ipproto(tp_name, l4num); + + if (l3num == AF_INET) { + ds_put_cstr(tp_name, "4"); + } else if (l3num == AF_INET6 && l4num != IPPROTO_ICMPV6) { + ds_put_cstr(tp_name, "6"); + } + + ovs_assert(tp_name->length < CTNL_TIMEOUT_NAME_MAX); +} + +#define CT_DPIF_TO_NL_TP_TCP_MAPPINGS \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, SYN_SENT, SYN_SENT) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, SYN_RECV, SYN_RECV) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, ESTABLISHED, ESTABLISHED) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, FIN_WAIT, FIN_WAIT) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, CLOSE_WAIT, CLOSE_WAIT) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, LAST_ACK, LAST_ACK) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, TIME_WAIT, TIME_WAIT) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, CLOSE, CLOSE) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, SYN_SENT2, SYN_SENT2) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, RETRANSMIT, RETRANS) \ + CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, UNACK, UNACK) + +#define CT_DPIF_TO_NL_TP_UDP_MAPPINGS \ + CT_DPIF_TO_NL_TP_MAPPING(UDP, UDP, FIRST, UNREPLIED) \ + CT_DPIF_TO_NL_TP_MAPPING(UDP, UDP, MULTIPLE, REPLIED) + +#define CT_DPIF_TO_NL_TP_ICMP_MAPPINGS \ + CT_DPIF_TO_NL_TP_MAPPING(ICMP, ICMP, FIRST, TIMEOUT) + +#define CT_DPIF_TO_NL_TP_ICMPV6_MAPPINGS \ + CT_DPIF_TO_NL_TP_MAPPING(ICMP, ICMPV6, FIRST, TIMEOUT) + + +#define CT_DPIF_TO_NL_TP_MAPPING(PROTO1, PROTO2, ATTR1, ATTR2) \ +if (tp->present & (1 << CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1)) { \ + nl_tp->present |= 1 << CTA_TIMEOUT_##PROTO2##_##ATTR2; \ + nl_tp->attrs[CTA_TIMEOUT_##PROTO2##_##ATTR2] = \ + tp->attrs[CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1]; \ +} + +static void +dpif_netlink_get_nl_tp_tcp_attrs(const struct ct_dpif_timeout_policy *tp, + struct nl_ct_timeout_policy *nl_tp) +{ + CT_DPIF_TO_NL_TP_TCP_MAPPINGS +} + +static void +dpif_netlink_get_nl_tp_udp_attrs(const struct ct_dpif_timeout_policy *tp, + struct nl_ct_timeout_policy *nl_tp) +{ + CT_DPIF_TO_NL_TP_UDP_MAPPINGS +} + +static void +dpif_netlink_get_nl_tp_icmp_attrs(const struct ct_dpif_timeout_policy *tp, + struct nl_ct_timeout_policy *nl_tp) +{ + CT_DPIF_TO_NL_TP_ICMP_MAPPINGS +} + +static void +dpif_netlink_get_nl_tp_icmpv6_attrs(const struct ct_dpif_timeout_policy *tp, + struct nl_ct_timeout_policy *nl_tp) +{ + CT_DPIF_TO_NL_TP_ICMPV6_MAPPINGS +} + +#undef CT_DPIF_TO_NL_TP_MAPPING + +static void +dpif_netlink_get_nl_tp_attrs(const struct ct_dpif_timeout_policy *tp, + uint8_t l4num, struct nl_ct_timeout_policy *nl_tp) +{ + nl_tp->present = 0; + + if (l4num == IPPROTO_TCP) { + dpif_netlink_get_nl_tp_tcp_attrs(tp, nl_tp); + } else if (l4num == IPPROTO_UDP) { + dpif_netlink_get_nl_tp_udp_attrs(tp, nl_tp); + } else if (l4num == IPPROTO_ICMP) { + dpif_netlink_get_nl_tp_icmp_attrs(tp, nl_tp); + } else if (l4num == IPPROTO_ICMPV6) { + dpif_netlink_get_nl_tp_icmpv6_attrs(tp, nl_tp); + } +} + +#define CT_DPIF_TO_NL_TP_MAPPING(PROTO1, PROTO2, ATTR1, ATTR2) \ +if (nl_tp->present & (1 << CTA_TIMEOUT_##PROTO2##_##ATTR2)) { \ + tp->present |= 1 << CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1; \ + tp->attrs[CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1] = \ + nl_tp->attrs[CTA_TIMEOUT_##PROTO2##_##ATTR2]; \ + } + +static void +dpif_netlink_set_ct_dpif_tp_tcp_attrs(const struct nl_ct_timeout_policy *nl_tp, + struct ct_dpif_timeout_policy *tp) +{ + CT_DPIF_TO_NL_TP_TCP_MAPPINGS +} + +static void +dpif_netlink_set_ct_dpif_tp_udp_attrs(const struct nl_ct_timeout_policy *nl_tp, + struct ct_dpif_timeout_policy *tp) +{ + CT_DPIF_TO_NL_TP_UDP_MAPPINGS +} + +static void +dpif_netlink_set_ct_dpif_tp_icmp_attrs( + const struct nl_ct_timeout_policy *nl_tp, + struct ct_dpif_timeout_policy *tp) +{ + CT_DPIF_TO_NL_TP_ICMP_MAPPINGS +} + +static void +dpif_netlink_set_ct_dpif_tp_icmpv6_attrs( + const struct nl_ct_timeout_policy *nl_tp, + struct ct_dpif_timeout_policy *tp) +{ + CT_DPIF_TO_NL_TP_ICMPV6_MAPPINGS +} + +#undef CT_DPIF_TO_NL_TP_MAPPING + +static void +dpif_netlink_set_ct_dpif_tp_attrs(const struct nl_ct_timeout_policy *nl_tp, + struct ct_dpif_timeout_policy *tp) +{ + if (nl_tp->l4num == IPPROTO_TCP) { + dpif_netlink_set_ct_dpif_tp_tcp_attrs(nl_tp, tp); + } else if (nl_tp->l4num == IPPROTO_UDP) { + dpif_netlink_set_ct_dpif_tp_udp_attrs(nl_tp, tp); + } else if (nl_tp->l4num == IPPROTO_ICMP) { + dpif_netlink_set_ct_dpif_tp_icmp_attrs(nl_tp, tp); + } else if (nl_tp->l4num == IPPROTO_ICMPV6) { + dpif_netlink_set_ct_dpif_tp_icmpv6_attrs(nl_tp, tp); + } +} + +static int +dpif_netlink_ct_add_timeout_policy(struct dpif *dpif OVS_UNUSED, + bool is_default, + const struct ct_dpif_timeout_policy *tp) +{ +#ifdef _WIN32 + return EOPNOTSUPP; +#else + struct nl_ct_timeout_policy nl_tp; + struct ds ds = DS_EMPTY_INITIALIZER; + int i, err; + + for (i = 0; i < ARRAY_SIZE(tp_protos); ++i) { + dpif_netlink_format_tp_name(tp->id, tp_protos[i].l3num, + tp_protos[i].l4num, &ds); + ovs_strlcpy(nl_tp.name, ds_cstr(&ds), sizeof nl_tp.name); + nl_tp.l3num = tp_protos[i].l3num; + nl_tp.l4num = tp_protos[i].l4num; + dpif_netlink_get_nl_tp_attrs(tp, tp_protos[i].l4num, &nl_tp); + if (!is_default) { + err = nl_ct_set_timeout_policy(&nl_tp); + } else if (tp_protos[i].l3num == AF_INET) { + /* The default timeout policy is shared between AF_INET and + * AF_INET6 in the kernel. So configure AF_INET is sufficient. */ + err = nl_ct_set_default_timeout_policy(&nl_tp); + } + if (err) { + VLOG_INFO("failed to set timeout policy %s (%s)", nl_tp.name, + ovs_strerror(err)); + return err; + } + } + + ds_destroy(&ds); + return 0; +#endif +} + +static int +dpif_netlink_ct_get_timeout_policy(struct dpif *dpif OVS_UNUSED, + bool is_default, uint32_t tp_id, + struct ct_dpif_timeout_policy *tp) +{ +#ifdef _WIN32 + return EOPNOTSUPP; +#else + struct nl_ct_timeout_policy nl_tp; + struct ds nl_tp_name = DS_EMPTY_INITIALIZER; + int i, err; + + tp->id = tp_id; + tp->present = 0; + for (i = 0; i < ARRAY_SIZE(tp_protos); ++i) { + if (!is_default) { + dpif_netlink_format_tp_name(tp_id, tp_protos[i].l3num, + tp_protos[i].l4num, &nl_tp_name); + err = nl_ct_get_timeout_policy(ds_cstr(&nl_tp_name), &nl_tp); + } else if (tp_protos[i].l3num == AF_INET) { + /* The default timeout is shared between AF_INET and AF_INET6 + * in the kernel. So get from AF_INET is sufficient. */ + err = nl_ct_get_default_timeout_policy(tp_protos[i].l3num, + tp_protos[i].l4num, &nl_tp); + } + if (err) { + return err; + } + dpif_netlink_set_ct_dpif_tp_attrs(&nl_tp, tp); + } + + ds_destroy(&nl_tp_name); + return 0; +#endif +} + +static int +dpif_netlink_ct_del_timeout_policy(struct dpif *dpif OVS_UNUSED, + uint32_t tp_id) +{ +#ifdef _WIN32 + return EOPNOTSUPP; +#else + struct ds nl_tp_name = DS_EMPTY_INITIALIZER; + int i, err; + + if (!tp_id) { + return EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(tp_protos); ++i) { + dpif_netlink_format_tp_name(tp_id, tp_protos[i].l3num, + tp_protos[i].l4num, &nl_tp_name); + err = nl_ct_del_timeout_policy(ds_cstr(&nl_tp_name)); + if (err) { + VLOG_INFO("failed to delete timeout policy %s (%s)", + ds_cstr(&nl_tp_name), ovs_strerror(err)); + return err; + } + } + + ds_destroy(&nl_tp_name); + return 0; +#endif +} + +struct dpif_netlink_ct_timeout_policy_dump_state { + struct nl_ct_timeout_policy_dump_state *nl_dump_state; + struct hmap tp_dump_map; +}; + +struct dpif_netlink_tp_dump_node { + struct hmap_node hmap_node; /* node in tp_dump_map. */ + struct ct_dpif_timeout_policy *tp; + uint32_t present; +}; + +static struct dpif_netlink_tp_dump_node * +get_dpif_netlink_tp_dump_node_by_tp_id(uint32_t tp_id, + struct hmap *tp_dump_map) +{ + struct dpif_netlink_tp_dump_node *tp_dump_node; + + HMAP_FOR_EACH_WITH_HASH (tp_dump_node, hmap_node, hash_int(tp_id, 0), + tp_dump_map) { + if (tp_dump_node->tp->id == tp_id) { + return tp_dump_node; + } + } + return NULL; +} + +static void +update_dpif_netlink_tp_dump_node( + const struct nl_ct_timeout_policy *nl_tp, + struct dpif_netlink_tp_dump_node *tp_dump_node) +{ + int i; + + dpif_netlink_set_ct_dpif_tp_attrs(nl_tp, tp_dump_node->tp); + for (i = 0; i < DPIF_NL_TP_MAX; ++i) { + if (nl_tp->l3num == tp_protos[i].l3num && + nl_tp->l4num == tp_protos[i].l4num) { + tp_dump_node->present |= 1 << i; + break; + } + } +} + +static int +dpif_netlink_ct_timeout_policy_dump_start(struct dpif *dpif OVS_UNUSED, + void **statep) +{ +#ifdef _WIN32 + return EOPNOTSUPP; +#else + struct dpif_netlink_ct_timeout_policy_dump_state *dump_state; + int err; + + *statep = dump_state = xzalloc(sizeof *dump_state); + err = nl_ct_timeout_policy_dump_start(&dump_state->nl_dump_state); + if (err) { + free(dump_state); + return err; + } + hmap_init(&dump_state->tp_dump_map); + return 0; +#endif +} + +static int +dpif_netlink_ct_timeout_policy_dump_next(struct dpif *dpif OVS_UNUSED, + void *state, + struct ct_dpif_timeout_policy **tp) +{ +#ifdef _WIN32 + return EOPNOTSUPP; +#else + struct dpif_netlink_ct_timeout_policy_dump_state *dump_state = state; + struct dpif_netlink_tp_dump_node *tp_dump_node; + struct nl_ct_timeout_policy nl_tp; + uint32_t tp_id; + int err; + + do { + err = nl_ct_timeout_policy_dump_next(dump_state->nl_dump_state, + &nl_tp); + if (err) { + break; + } + + if (!ovs_scan(nl_tp.name, NL_TP_NAME_PREFIX"%"PRIu32, &tp_id)) { + continue; + } + + tp_dump_node = get_dpif_netlink_tp_dump_node_by_tp_id( + tp_id, &dump_state->tp_dump_map); + if (!tp_dump_node) { + tp_dump_node = xzalloc(sizeof *tp_dump_node); + tp_dump_node->tp = xzalloc(sizeof *tp_dump_node->tp); + tp_dump_node->tp->id = tp_id; + hmap_insert(&dump_state->tp_dump_map, &tp_dump_node->hmap_node, + hash_int(tp_id, 0)); + } + + update_dpif_netlink_tp_dump_node(&nl_tp, tp_dump_node); + if (tp_dump_node->present == DPIF_NL_ALL_TP) { + hmap_remove(&dump_state->tp_dump_map, &tp_dump_node->hmap_node); + *tp = tp_dump_node->tp; + free(tp_dump_node); + break; + } + } while (true); + return err; +#endif +} + +static int +dpif_netlink_ct_timeout_policy_dump_done(struct dpif *dpif OVS_UNUSED, + void *state) +{ +#ifdef _WIN32 + return EOPNOTSUPP; +#else + struct dpif_netlink_ct_timeout_policy_dump_state *dump_state = state; + struct dpif_netlink_tp_dump_node *tp_dump_node; + int err; + + err = nl_ct_timeout_policy_dump_done(dump_state->nl_dump_state); + /* clear dump map, modulize */ + HMAP_FOR_EACH_POP (tp_dump_node, hmap_node, &dump_state->tp_dump_map) { + VLOG_INFO("Partial timeout policy in dpif-netlink %"PRIu32, + tp_dump_node->tp->id); + free(tp_dump_node->tp); + free(tp_dump_node); + } + hmap_destroy(&dump_state->tp_dump_map); + free(dump_state); + return err; +#endif +} + /* Meters */ @@ -3434,12 +3854,12 @@ const struct dpif_class dpif_netlink_class = { dpif_netlink_ct_set_limits, dpif_netlink_ct_get_limits, dpif_netlink_ct_del_limits, - NULL, /* ct_set_timeout_policy */ - NULL, /* ct_get_timeout_policy */ - NULL, /* ct_del_timeout_policy */ - NULL, /* ct_timeout_policy_dump_start */ - NULL, /* ct_timeout_policy_dump_next */ - NULL, /* ct_timeout_policy_dump_done */ + dpif_netlink_ct_add_timeout_policy, + dpif_netlink_ct_get_timeout_policy, + dpif_netlink_ct_del_timeout_policy, + dpif_netlink_ct_timeout_policy_dump_start, + dpif_netlink_ct_timeout_policy_dump_next, + dpif_netlink_ct_timeout_policy_dump_done, NULL, /* ipf_set_enabled */ NULL, /* ipf_set_min_frag */ NULL, /* ipf_set_max_nfrags */ diff --git a/lib/dpif-netlink.h b/lib/dpif-netlink.h index 0a9628088275..7e75120161f6 100644 --- a/lib/dpif-netlink.h +++ b/lib/dpif-netlink.h @@ -23,6 +23,7 @@ #include "odp-netlink.h" #include "flow.h" +#include "netlink-conntrack.h" struct ofpbuf; @@ -50,7 +51,6 @@ struct dpif_netlink_vport { }; void dpif_netlink_vport_init(struct dpif_netlink_vport *); - int dpif_netlink_vport_transact(const struct dpif_netlink_vport *request, struct dpif_netlink_vport *reply, struct ofpbuf **bufp); diff --git a/lib/netlink-conntrack.c b/lib/netlink-conntrack.c index 7631ba5d5d31..9bc0ddb66248 100644 --- a/lib/netlink-conntrack.c +++ b/lib/netlink-conntrack.c @@ -840,6 +840,369 @@ nl_ct_parse_helper(struct nlattr *nla, struct ct_dpif_helper *helper) return parsed; } +static int nl_ct_timeout_policy_max_attr[] = { + [IPPROTO_TCP] = CTA_TIMEOUT_TCP_MAX, + [IPPROTO_UDP] = CTA_TIMEOUT_UDP_MAX, + [IPPROTO_ICMP] = CTA_TIMEOUT_ICMP_MAX, + [IPPROTO_ICMPV6] = CTA_TIMEOUT_ICMPV6_MAX +}; + +static void +nl_ct_set_timeout_policy_attr(struct nl_ct_timeout_policy *nl_tp, + uint32_t attr, uint32_t val) +{ + nl_tp->present |= 1 << attr; + nl_tp->attrs[attr] = val; +} + +static int +nl_ct_parse_tcp_timeout_policy_data(struct nlattr *nla, + struct nl_ct_timeout_policy *nl_tp) +{ + static const struct nl_policy policy[] = { + [CTA_TIMEOUT_TCP_SYN_SENT] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_SYN_RECV] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_ESTABLISHED] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_FIN_WAIT] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_CLOSE_WAIT] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_LAST_ACK] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_TIME_WAIT] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_CLOSE] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_SYN_SENT2] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_RETRANS] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_TCP_UNACK] = { .type = NL_A_BE32, + .optional = false }, + }; + struct nlattr *attrs[ARRAY_SIZE(policy)]; + int i; + + if (!nl_parse_nested(nla, policy, attrs, ARRAY_SIZE(policy))) { + VLOG_ERR_RL(&rl, "Could not parse nested tcp timeout options. " + "Possibly incompatible Linux kernel version."); + return EINVAL; + } + + for (i = CTA_TIMEOUT_TCP_SYN_SENT; i <= CTA_TIMEOUT_TCP_UNACK; i++) { + nl_ct_set_timeout_policy_attr(nl_tp, i, + ntohl(nl_attr_get_be32(attrs[i]))); + } + return 0; +} + +static int +nl_ct_parse_udp_timeout_policy_data(struct nlattr *nla, + struct nl_ct_timeout_policy *nl_tp) +{ + static const struct nl_policy policy[] = { + [CTA_TIMEOUT_UDP_UNREPLIED] = { .type = NL_A_BE32, + .optional = false }, + [CTA_TIMEOUT_UDP_REPLIED] = { .type = NL_A_BE32, + .optional = false }, + }; + struct nlattr *attrs[ARRAY_SIZE(policy)]; + int i; + + if (!nl_parse_nested(nla, policy, attrs, ARRAY_SIZE(policy))) { + VLOG_ERR_RL(&rl, "Could not parse nested tcp timeout options. " + "Possibly incompatible Linux kernel version."); + return EINVAL; + } + + for (i = CTA_TIMEOUT_UDP_UNREPLIED; i <= CTA_TIMEOUT_UDP_REPLIED; i++) { + nl_ct_set_timeout_policy_attr(nl_tp, i, + ntohl(nl_attr_get_be32(attrs[i]))); + } + return 0; +} + +static int +nl_ct_parse_icmp_timeout_policy_data(struct nlattr *nla, + struct nl_ct_timeout_policy *nl_tp) +{ + static const struct nl_policy policy[] = { + [CTA_TIMEOUT_ICMP_TIMEOUT] = { .type = NL_A_BE32, + .optional = false }, + }; + struct nlattr *attrs[ARRAY_SIZE(policy)]; + + if (!nl_parse_nested(nla, policy, attrs, ARRAY_SIZE(policy))) { + VLOG_ERR_RL(&rl, "Could not parse nested icmp timeout options. " + "Possibly incompatible Linux kernel version."); + return EINVAL; + } + + nl_ct_set_timeout_policy_attr( + nl_tp, CTA_TIMEOUT_ICMP_TIMEOUT, + ntohl(nl_attr_get_be32(attrs[CTA_TIMEOUT_ICMP_TIMEOUT]))); + return 0; +} + +static int +nl_ct_parse_icmpv6_timeout_policy_data(struct nlattr *nla, + struct nl_ct_timeout_policy *nl_tp) +{ + static const struct nl_policy policy[] = { + [CTA_TIMEOUT_ICMPV6_TIMEOUT] = { .type = NL_A_BE32, + .optional = false }, + }; + struct nlattr *attrs[ARRAY_SIZE(policy)]; + + if (!nl_parse_nested(nla, policy, attrs, ARRAY_SIZE(policy))) { + VLOG_ERR_RL(&rl, "Could not parse nested icmpv6 timeout options. " + "Possibly incompatible Linux kernel version."); + return EINVAL; + } + + nl_ct_set_timeout_policy_attr( + nl_tp, CTA_TIMEOUT_ICMPV6_TIMEOUT, + ntohl(nl_attr_get_be32(attrs[CTA_TIMEOUT_ICMPV6_TIMEOUT]))); + return 0; +} + +static int +nl_ct_parse_timeout_policy_data(struct nlattr *nla, + struct nl_ct_timeout_policy *nl_tp) +{ + switch (nl_tp->l4num) { + case IPPROTO_TCP: + return nl_ct_parse_tcp_timeout_policy_data(nla, nl_tp); + case IPPROTO_UDP: + return nl_ct_parse_udp_timeout_policy_data(nla, nl_tp); + case IPPROTO_ICMP: + return nl_ct_parse_icmp_timeout_policy_data(nla, nl_tp); + case IPPROTO_ICMPV6: + return nl_ct_parse_icmpv6_timeout_policy_data(nla, nl_tp); + default: + return EINVAL; + } +} + +static int +nl_ct_timeout_policy_from_ofpbuf(struct ofpbuf *buf, + struct nl_ct_timeout_policy *nl_tp, + bool default_tp) +{ + static const struct nl_policy policy[] = { + [CTA_TIMEOUT_NAME] = { .type = NL_A_STRING, .optional = false }, + [CTA_TIMEOUT_L3PROTO] = { .type = NL_A_BE16, .optional = false }, + [CTA_TIMEOUT_L4PROTO] = { .type = NL_A_U8, .optional = false }, + [CTA_TIMEOUT_DATA] = { .type = NL_A_NESTED, .optional = false } + }; + static const struct nl_policy policy_default_tp[] = { + [CTA_TIMEOUT_L3PROTO] = { .type = NL_A_BE16, .optional = false }, + [CTA_TIMEOUT_L4PROTO] = { .type = NL_A_U8, .optional = false }, + [CTA_TIMEOUT_DATA] = { .type = NL_A_NESTED, .optional = false } + }; + + struct nlattr *attrs[ARRAY_SIZE(policy)]; + struct ofpbuf b = ofpbuf_const_initializer(buf->data, buf->size); + struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); + struct nfgenmsg *nfmsg = ofpbuf_try_pull(&b, sizeof *nfmsg); + int err; + + if (!nlmsg || !nfmsg + || NFNL_SUBSYS_ID(nlmsg->nlmsg_type) != NFNL_SUBSYS_CTNETLINK_TIMEOUT + || nfmsg->version != NFNETLINK_V0 + || !nl_policy_parse(&b, 0, default_tp ? policy_default_tp : policy, + attrs, default_tp ? ARRAY_SIZE(policy_default_tp) : + ARRAY_SIZE(policy))) { + return EINVAL; + } + + if (!default_tp) { + ovs_strlcpy(nl_tp->name, nl_attr_get_string(attrs[CTA_TIMEOUT_NAME]), + sizeof nl_tp->name); + } + nl_tp->l3num = ntohs(nl_attr_get_be16(attrs[CTA_TIMEOUT_L3PROTO])); + nl_tp->l4num = nl_attr_get_u8(attrs[CTA_TIMEOUT_L4PROTO]); + nl_tp->present = 0; + + err = nl_ct_parse_timeout_policy_data(attrs[CTA_TIMEOUT_DATA], nl_tp); + return err; +} + +int +nl_ct_set_timeout_policy(const struct nl_ct_timeout_policy *nl_tp) +{ + struct ofpbuf buf; + size_t offset; + int i, err; + + ofpbuf_init(&buf, 512); + nl_msg_put_nfgenmsg(&buf, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK_TIMEOUT, + IPCTNL_MSG_TIMEOUT_NEW, NLM_F_REQUEST | NLM_F_CREATE + | NLM_F_ACK | NLM_F_REPLACE); + + nl_msg_put_string(&buf, CTA_TIMEOUT_NAME, nl_tp->name); + nl_msg_put_be16(&buf, CTA_TIMEOUT_L3PROTO, htons(nl_tp->l3num)); + nl_msg_put_u8(&buf, CTA_TIMEOUT_L4PROTO, nl_tp->l4num); + + offset = nl_msg_start_nested(&buf, CTA_TIMEOUT_DATA); + for (i = 1; i <= nl_ct_timeout_policy_max_attr[nl_tp->l4num]; ++i) { + if (nl_tp->present & 1 << i) { + nl_msg_put_be32(&buf, i, htonl(nl_tp->attrs[i])); + } + } + nl_msg_end_nested(&buf, offset); + + err = nl_transact(NETLINK_NETFILTER, &buf, NULL); + ofpbuf_uninit(&buf); + return err; +} + +int +nl_ct_set_default_timeout_policy(const struct nl_ct_timeout_policy *nl_tp) +{ + struct ofpbuf buf; + size_t offset; + int i, err; + + ofpbuf_init(&buf, 512); + nl_msg_put_nfgenmsg(&buf, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK_TIMEOUT, + IPCTNL_MSG_TIMEOUT_DEFAULT_SET, NLM_F_REQUEST + | NLM_F_ACK | NLM_F_REPLACE); + + nl_msg_put_be16(&buf, CTA_TIMEOUT_L3PROTO, htons(nl_tp->l3num)); + nl_msg_put_u8(&buf, CTA_TIMEOUT_L4PROTO, nl_tp->l4num); + + offset = nl_msg_start_nested(&buf, CTA_TIMEOUT_DATA); + for (i = 1; i <= nl_ct_timeout_policy_max_attr[nl_tp->l4num]; ++i) { + if (nl_tp->present & 1 << i) { + nl_msg_put_be32(&buf, i, htonl(nl_tp->attrs[i])); + } + } + nl_msg_end_nested(&buf, offset); + + err = nl_transact(NETLINK_NETFILTER, &buf, NULL); + ofpbuf_uninit(&buf); + return err; +} + +int +nl_ct_get_timeout_policy(const char *tp_name, + struct nl_ct_timeout_policy *nl_tp) +{ + struct ofpbuf request, *reply; + int err; + + ofpbuf_init(&request, 512); + nl_msg_put_nfgenmsg(&request, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK_TIMEOUT, + IPCTNL_MSG_TIMEOUT_GET, NLM_F_REQUEST | NLM_F_ACK); + nl_msg_put_string(&request, CTA_TIMEOUT_NAME, tp_name); + err = nl_transact(NETLINK_NETFILTER, &request, &reply); + if (err) { + goto out; + } + + err = nl_ct_timeout_policy_from_ofpbuf(reply, nl_tp, false); + +out: + ofpbuf_uninit(&request); + ofpbuf_delete(reply); + return err; +} + +int +nl_ct_get_default_timeout_policy(uint16_t l3num, uint8_t l4num, + struct nl_ct_timeout_policy *nl_tp) +{ + struct ofpbuf request, *reply; + int err; + + ofpbuf_init(&request, 512); + nl_msg_put_nfgenmsg(&request, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK_TIMEOUT, + IPCTNL_MSG_TIMEOUT_DEFAULT_GET, + NLM_F_REQUEST | NLM_F_ACK); + + nl_msg_put_be16(&request, CTA_TIMEOUT_L3PROTO, htons(l3num)); + nl_msg_put_u8(&request, CTA_TIMEOUT_L4PROTO, l4num); + err = nl_transact(NETLINK_NETFILTER, &request, &reply); + if (err) { + goto out; + } + + err = nl_ct_timeout_policy_from_ofpbuf(reply, nl_tp, true); + +out: + ofpbuf_uninit(&request); + ofpbuf_delete(reply); + return err; +} + +int +nl_ct_del_timeout_policy(const char *tp_name) +{ + struct ofpbuf buf; + int err; + + ofpbuf_init(&buf, 64); + nl_msg_put_nfgenmsg(&buf, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK_TIMEOUT, + IPCTNL_MSG_TIMEOUT_DELETE, NLM_F_REQUEST | NLM_F_ACK); + + nl_msg_put_string(&buf, CTA_TIMEOUT_NAME, tp_name); + err = nl_transact(NETLINK_NETFILTER, &buf, NULL); + ofpbuf_uninit(&buf); + return err; +} + +struct nl_ct_timeout_policy_dump_state { + struct nl_dump dump; + struct ofpbuf buf; +}; + +int +nl_ct_timeout_policy_dump_start( + struct nl_ct_timeout_policy_dump_state **statep) +{ + struct ofpbuf request; + struct nl_ct_timeout_policy_dump_state *state; + + *statep = state = xzalloc(sizeof *state); + ofpbuf_init(&request, 512); + nl_msg_put_nfgenmsg(&request, 0, AF_UNSPEC, NFNL_SUBSYS_CTNETLINK_TIMEOUT, + IPCTNL_MSG_TIMEOUT_GET, + NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP); + + nl_dump_start(&state->dump, NETLINK_NETFILTER, &request); + ofpbuf_uninit(&request); + ofpbuf_init(&state->buf, NL_DUMP_BUFSIZE); + return 0; +} + +int +nl_ct_timeout_policy_dump_next(struct nl_ct_timeout_policy_dump_state *state, + struct nl_ct_timeout_policy *nl_tp) +{ + struct ofpbuf reply; + int err; + + if (!nl_dump_next(&state->dump, &reply, &state->buf)) { + return EOF; + } + err = nl_ct_timeout_policy_from_ofpbuf(&reply, nl_tp, false); + ofpbuf_uninit(&reply); + return err; +} + +int +nl_ct_timeout_policy_dump_done(struct nl_ct_timeout_policy_dump_state *state) +{ + int err = nl_dump_done(&state->dump); + ofpbuf_uninit(&state->buf); + free(state); + return err; +} + /* Translate netlink entry status flags to CT_DPIF_TCP status flags. */ static uint32_t ips_status_to_dpif_flags(uint32_t status) diff --git a/lib/netlink-conntrack.h b/lib/netlink-conntrack.h index 8b536fd65ba8..ae6e428e0929 100644 --- a/lib/netlink-conntrack.h +++ b/lib/netlink-conntrack.h @@ -17,9 +17,12 @@ #ifndef NETLINK_CONNTRACK_H #define NETLINK_CONNTRACK_H +#include + #include "byte-order.h" #include "compiler.h" #include "ct-dpif.h" +#include "netlink-socket.h" #include "openvswitch/dynamic-string.h" #include "openvswitch/hmap.h" #include "openvswitch/ofpbuf.h" @@ -33,7 +36,18 @@ enum nl_ct_event_type { NL_CT_EVENT_DELETE = 1 << 2, }; +#define NL_CT_TIMEOUT_POLICY_MAX_ATTR (CTA_TIMEOUT_TCP_MAX + 1) + +struct nl_ct_timeout_policy { + char name[CTNL_TIMEOUT_NAME_MAX]; + uint16_t l3num; + uint8_t l4num; + uint32_t attrs[NL_CT_TIMEOUT_POLICY_MAX_ATTR]; + uint32_t present; +}; + struct nl_ct_dump_state; +struct nl_ct_timeout_policy_dump_state; int nl_ct_dump_start(struct nl_ct_dump_state **, const uint16_t *zone, int *ptot_bkts); @@ -44,6 +58,21 @@ int nl_ct_flush(void); int nl_ct_flush_zone(uint16_t zone); int nl_ct_flush_tuple(const struct ct_dpif_tuple *, uint16_t zone); +int nl_ct_set_timeout_policy(const struct nl_ct_timeout_policy *nl_tp); +int nl_ct_set_default_timeout_policy(const struct nl_ct_timeout_policy *nl_tp); +int nl_ct_get_timeout_policy(const char *tp_name, + struct nl_ct_timeout_policy *nl_tp); +int nl_ct_get_default_timeout_policy(uint16_t l3num, uint8_t l4num, + struct nl_ct_timeout_policy *nl_tp); +int nl_ct_del_timeout_policy(const char *tp_name); +int nl_ct_timeout_policy_dump_start( + struct nl_ct_timeout_policy_dump_state **statep); +int nl_ct_timeout_policy_dump_next( + struct nl_ct_timeout_policy_dump_state *state, + struct nl_ct_timeout_policy *nl_tp); +int nl_ct_timeout_policy_dump_done( + struct nl_ct_timeout_policy_dump_state *state); + bool nl_ct_parse_entry(struct ofpbuf *, struct ct_dpif_entry *, enum nl_ct_event_type *); void nl_ct_format_event_entry(const struct ct_dpif_entry *, diff --git a/lib/netlink-protocol.h b/lib/netlink-protocol.h index c0617dfad21f..bf631b1a14d0 100644 --- a/lib/netlink-protocol.h +++ b/lib/netlink-protocol.h @@ -48,6 +48,7 @@ #define NLM_F_ECHO 0x008 #define NLM_F_ROOT 0x100 +#define NLM_F_REPLACE 0x100 #define NLM_F_MATCH 0x200 #define NLM_F_EXCL 0x200 #define NLM_F_ATOMIC 0x400 From patchwork Thu Jul 25 23:24:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137167 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="MdYAJ0hP"; 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 45vpM72jdtz9s4Y for ; Fri, 26 Jul 2019 09:29:07 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 9CCB8D7E; Thu, 25 Jul 2019 23:24:42 +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 AAB40CAE for ; Thu, 25 Jul 2019 23:24:39 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 29FCB701 for ; Thu, 25 Jul 2019 23:24:38 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id l21so23777262pgm.3 for ; Thu, 25 Jul 2019 16:24:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YTqNsg7phXl05Led6OHT49nuL0uiRiot/pAQ7BaSTCo=; b=MdYAJ0hP85JYawWQBJTwlu3tUX26QK8gWdiId8J0sVmVMwmuwBoFRS1/7h7gWDCtyF rgtzADg9Ph0bmLwy+ww84HG1QDUY+wrBkz0slc4/cs2qHB5A3IyFAcz37AXkdOE2ErH/ pLebRNmDL5oSpR9UtkvsuaDkyo2DX08Q2HPYR9hwtyzwDRiFWoP5uiDSZihF7qwZXzph w8YINKsRIfvem88hhpj+NFCl2AKjH1KLSUy7/2EaYJRgOdvzmNCATWYQDmFvHGy6r8KZ evyhGx+Gtn+eeiPQ0Grd3lU8I7h1fJDPT6ATsH0XpG8m9ZwDnhJVHIFDs8tKcNlcaRgt Qxeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=YTqNsg7phXl05Led6OHT49nuL0uiRiot/pAQ7BaSTCo=; b=GrfXDzdqRDiog57zW2EFZ5qdWSJaS0yeGqyi5RvZ5F9s/zEyRKHINzVh8xeYiGe5lS asz8G8p56Db+tUXOEmVoRiacg5373rviMqJB+AapBjPRex70/i0/Lh60v299GVzcQUPS fXNDBNAjYmokLCC2Jhl+dnrAPI42TIioIijVsf7gZL4a+QZXpXIXhyS5Om9EDCuK5JYJ qrZVfNppLUXTQSe5ELaNTrPtlLOSr42069N3O9eD7Gu6leqnyK3rpKyapQRFmK9poJ0K ensqK8mCBR/NaaNMO7oO1wRC1r7SFGMFyWmrWtxXCwXI8OyjtccozBiZEg0aw/2jHjAu /8sQ== X-Gm-Message-State: APjAAAVr/sQNG/OKSmU8zriTaq/U/k+UXUDNuegup8pOnl9qR0/VqRu+ Dh+qAWJYp7d1C2xTpFfsFX55Yk6f X-Google-Smtp-Source: APXvYqyT2pJ7PQIGzSDXKlOlrj437U0tqeLxdF6UrYGeXV7UrXWcKflwNlHoG5e92q82v4Qi3BIjZA== X-Received: by 2002:a62:b411:: with SMTP id h17mr18243840pfn.99.1564097077255; Thu, 25 Jul 2019 16:24:37 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:36 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:10 -0700 Message-Id: <1564097054-72663-9-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 08/12] datapath-config: Consume datapath, CT_Zone, and CT_Timeout_Policy tables 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 This patch reads the datapath, CT_Zone, and CT_Timeout_Policy tables from ovsdb, stores the information in a per datapath internal datapath structure, and pushes down the conntrack timeout policy into the datapath via dpif interface. The per datapath internal data structure will be used in ofproto-dpif-xlate to implement the zone-based timeout policy. Signed-off-by: Yi-Hung Wei --- lib/automake.mk | 2 + lib/datapath-config.c | 379 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/datapath-config.h | 25 ++++ vswitchd/bridge.c | 3 + 4 files changed, 409 insertions(+) create mode 100644 lib/datapath-config.c create mode 100644 lib/datapath-config.h diff --git a/lib/automake.mk b/lib/automake.mk index 17b36b43d9d7..7532153f5d02 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -67,6 +67,8 @@ lib_libopenvswitch_la_SOURCES = \ lib/daemon.c \ lib/daemon.h \ lib/daemon-private.h \ + lib/datapath-config.c \ + lib/datapath-config.h \ lib/db-ctl-base.c \ lib/db-ctl-base.h \ lib/dhcp.h \ diff --git a/lib/datapath-config.c b/lib/datapath-config.c new file mode 100644 index 000000000000..cdd2128a60bc --- /dev/null +++ b/lib/datapath-config.c @@ -0,0 +1,379 @@ +/* Copyright (c) 2019 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 "datapath-config.h" + +#include "cmap.h" +#include "ct-dpif.h" +#include "dpif.h" +#include "openvswitch/vlog.h" + +VLOG_DEFINE_THIS_MODULE(datapath_config); + +struct ct_timeout_policy { + struct uuid uuid; + unsigned int last_used_seqno; + unsigned int last_updated_seqno; + struct ct_dpif_timeout_policy cdtp; + struct cmap_node node; /* Element in struct datapath's + * "ct_timeout_policies" cmap. */ +}; + +struct ct_zone { + uint16_t id; + unsigned int last_used_seqno; + struct uuid tp_uuid; /* uuid that identifies a timeout policy in + * struct datapaths's "ct_tps cmap. */ + struct cmap_node node; /* Element in struct datapath's "ct_zones" + * cmap. */ +}; + +struct datapath { + char *type; /* Datapath type. */ + char *dpif_backer_name; + const struct ovsrec_datapath *cfg; + + struct hmap_node node; /* In 'all_datapaths'. */ + struct cmap ct_zones; /* "struct ct_zone"s indexed by zone id. */ + struct cmap ct_tps; /* "struct ct_timeout_policy"s indexed by + * uuid. */ +}; + +/* All datapaths, indexed by type. */ +static struct hmap all_datapaths = HMAP_INITIALIZER(&all_datapaths); + +static void ct_zone_destroy(struct datapath *, struct ct_zone *); +static void ct_timeout_policy_destroy(struct datapath *, + struct ct_timeout_policy *, + struct dpif *); + +static struct datapath * +datapath_lookup(const char *type) +{ + struct datapath *dp; + + HMAP_FOR_EACH_WITH_HASH (dp, node, hash_string(type, 0), &all_datapaths) { + if (!strcmp(dp->type, type)) { + return dp; + } + } + return NULL; +} + +static void +datapath_clear_timeout_policy(struct datapath *dp) +{ + struct ct_dpif_timeout_policy *tp; + struct dpif *dpif; + void *state; + int err; + + dpif_open(dp->dpif_backer_name, dp->type, &dpif); + if (!dpif) { + return; + } + + err = ct_dpif_timeout_policy_dump_start(dpif, &state); + if (err) { + return ; + } + + while (!(err = ct_dpif_timeout_policy_dump_next(dpif, state, &tp))) { + ct_dpif_del_timeout_policy(dpif, tp->id); + free(tp); + } + + ct_dpif_timeout_policy_dump_done(dpif, state); + dpif_close(dpif); +} + +static struct datapath * +datapath_create(const struct ovsrec_datapath *dp_cfg, const char *type) +{ + struct datapath *dp; + + ovs_assert(!datapath_lookup(type)); + dp = xzalloc(sizeof *dp); + + dp->type = xstrdup(type); + dp->dpif_backer_name = xasprintf("ovs-%s", type); + dp->cfg = dp_cfg; + + cmap_init(&dp->ct_zones); + cmap_init(&dp->ct_tps); + + datapath_clear_timeout_policy(dp); + hmap_insert(&all_datapaths, &dp->node, hash_string(dp->type, 0)); + return dp; +} + +static void +datapath_destroy(struct datapath *dp) +{ + struct ct_zone *zone; + struct ct_timeout_policy *tp; + struct dpif *dpif; + + if (dp) { + CMAP_FOR_EACH (zone, node, &dp->ct_zones) { + ct_zone_destroy(dp, zone); + } + + dpif_open(dp->dpif_backer_name, dp->type, &dpif); + + CMAP_FOR_EACH (tp, node, &dp->ct_tps) { + ct_timeout_policy_destroy(dp, tp, dpif); + } + + dpif_close(dpif); + hmap_remove(&all_datapaths, &dp->node); + cmap_destroy(&dp->ct_zones); + cmap_destroy(&dp->ct_tps); + free(dp->type); + free(dp->dpif_backer_name); + free(dp); + } +} + +static void +add_del_datapaths(const struct ovsrec_open_vswitch *cfg) +{ + struct datapath *dp, *next; + struct shash_node *node; + struct shash new_dp; + size_t i; + + /* Collect new datapaths' type. */ + shash_init(&new_dp); + for (i = 0; i < cfg->n_datapaths; i++) { + const struct ovsrec_datapath *dp_cfg = cfg->value_datapaths[i]; + char *key = cfg->key_datapaths[i]; + + if (!strcmp(key, "system") || !strcmp(key, "netdev")) { + shash_add(&new_dp, key, dp_cfg); + } else { + VLOG_WARN("Unsupported dpatapath type %s\n", key); + } + } + + /* Get rid of deleted datapath. */ + HMAP_FOR_EACH_SAFE (dp, next, node, &all_datapaths) { + dp->cfg = shash_find_data(&new_dp, dp->type); + if (!dp->cfg) { + datapath_destroy(dp); + } + } + + /* Add new datapaths */ + SHASH_FOR_EACH (node, &new_dp) { + const struct ovsrec_datapath *dp_cfg = node->data; + if (!datapath_lookup(node->name)) { + datapath_create(dp_cfg, node->name); + } + } + + shash_destroy(&new_dp); +} + +static struct ct_zone * +ct_zone_lookup(struct cmap *ct_zones, uint16_t zone_id) +{ + struct ct_zone *zone; + + CMAP_FOR_EACH_WITH_HASH (zone, node, hash_int(zone_id, 0), ct_zones) { + if (zone->id == zone_id) { + return zone; + } + } + return NULL; +} + +static struct ct_zone * +ct_zone_alloc(uint16_t zone_id) +{ + struct ct_zone *zone; + + zone = xzalloc(sizeof *zone); + zone->id = zone_id; + + return zone; +} + +static void +ct_zone_destroy(struct datapath *dp, struct ct_zone *zone) +{ + cmap_remove(&dp->ct_zones, &zone->node, hash_int(zone->id, 0)); + ovsrcu_postpone(free, zone); +} + +static struct ct_timeout_policy * +ct_timeout_policy_lookup(struct cmap *ct_tps, struct uuid *uuid) +{ + struct ct_timeout_policy *tp; + + CMAP_FOR_EACH_WITH_HASH (tp, node, uuid_hash(uuid), ct_tps) { + if (uuid_equals(&tp->uuid, uuid)) { + return tp; + } + } + return NULL; +} + +static struct ct_timeout_policy * +ct_timeout_policy_alloc(struct ovsrec_ct_timeout_policy *tp_cfg, + unsigned int idl_seqno) +{ + struct ct_timeout_policy *tp; + size_t i; + + tp = xzalloc(sizeof *tp); + tp->uuid = tp_cfg->header_.uuid; + for (i = 0; i < tp_cfg->n_timeouts; i++) { + ct_dpif_set_timeout_policy_attr_by_name(&tp->cdtp, + tp_cfg->key_timeouts[i], tp_cfg->value_timeouts[i]); + } + tp->cdtp.id = idl_seqno; + tp->last_updated_seqno = idl_seqno; + + return tp; +} + +static bool +ct_timeout_policy_update(struct ovsrec_ct_timeout_policy *tp_cfg, + struct ct_timeout_policy *tp, + unsigned int idl_seqno) +{ + size_t i; + bool changed = false; + + for (i = 0; i < tp_cfg->n_timeouts; i++) { + changed |= ct_dpif_set_timeout_policy_attr_by_name(&tp->cdtp, + tp_cfg->key_timeouts[i], tp_cfg->value_timeouts[i]); + } + if (changed) { + tp->last_updated_seqno = idl_seqno; + } + return changed; +} + +static void +ct_timeout_policy_destroy(struct datapath *dp, struct ct_timeout_policy *tp, + struct dpif *dpif) +{ + cmap_remove(&dp->ct_tps, &tp->node, uuid_hash(&tp->uuid)); + if (dpif) { + ct_dpif_del_timeout_policy(dpif, tp->cdtp.id); + } + ovsrcu_postpone(free, tp); +} + +static void +datapath_update_ct_zone_config(struct datapath *dp, struct dpif *dpif, + unsigned int idl_seqno) +{ + const struct ovsrec_datapath *dp_cfg = dp->cfg; + struct ovsrec_ct_timeout_policy *tp_cfg; + struct ovsrec_ct_zone *zone_cfg; + struct ct_timeout_policy *tp; + struct ct_zone *zone; + uint16_t zone_id; + bool new_zone; + size_t i; + + for (i = 0; i < dp_cfg->n_ct_zones; i++) { + /* Update ct_zone config */ + zone_cfg = dp_cfg->value_ct_zones[i]; + zone_id = dp_cfg->key_ct_zones[i]; + zone = ct_zone_lookup(&dp->ct_zones, zone_id); + if (!zone) { + new_zone = true; + zone = ct_zone_alloc(zone_id); + } else { + new_zone = false; + } + zone->last_used_seqno = idl_seqno; + + /* Update timeout policy */ + tp_cfg = zone_cfg->timeout_policy; + tp = ct_timeout_policy_lookup(&dp->ct_tps, &tp_cfg->header_.uuid); + if (!tp) { + tp = ct_timeout_policy_alloc(tp_cfg, idl_seqno); + cmap_insert(&dp->ct_tps, &tp->node, uuid_hash(&tp->uuid)); + if (dpif) { + ct_dpif_add_timeout_policy(dpif, false, &tp->cdtp); + } + } else { + if (ct_timeout_policy_update(tp_cfg, tp, idl_seqno)) { + if (dpif) { + ct_dpif_add_timeout_policy(dpif, false, &tp->cdtp); + } + } + } + tp->last_used_seqno = idl_seqno; + + /* Update default timeout policy */ + if (!zone_id && tp->last_updated_seqno == idl_seqno) { + ct_dpif_add_timeout_policy(dpif, true, &tp->cdtp); + } + + /* Link zone with new timeout policy */ + zone->tp_uuid = tp_cfg->header_.uuid; + if (new_zone) { + cmap_insert(&dp->ct_zones, &zone->node, hash_int(zone_id, 0)); + } + } +} + +void +reconfigure_datapath(const struct ovsrec_open_vswitch *cfg, + unsigned int idl_seqno) +{ + struct ct_timeout_policy *tp; + struct ct_zone *zone; + struct datapath *dp; + struct dpif *dpif; + + add_del_datapaths(cfg); + HMAP_FOR_EACH (dp, node, &all_datapaths) { + dpif_open(dp->dpif_backer_name, dp->type, &dpif); + + datapath_update_ct_zone_config(dp, dpif, idl_seqno); + + /* Garbage colleciton */ + CMAP_FOR_EACH (zone, node, &dp->ct_zones) { + if (zone->last_used_seqno != idl_seqno) { + ct_zone_destroy(dp, zone); + } + } + CMAP_FOR_EACH (tp, node, &dp->ct_tps) { + if (tp->last_used_seqno != idl_seqno) { + ct_timeout_policy_destroy(dp, tp, dpif); + } + } + + dpif_close(dpif); + } +} + +void +destroy_all_datapaths(void) +{ + struct datapath *dp, *next_dp; + + HMAP_FOR_EACH_SAFE (dp, next_dp, node, &all_datapaths) { + datapath_destroy(dp); + } +} diff --git a/lib/datapath-config.h b/lib/datapath-config.h new file mode 100644 index 000000000000..d9a90e4f8312 --- /dev/null +++ b/lib/datapath-config.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2019 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 DATAPATH_CONFIG_H +#define DATAPATH_CONFIG_H 1 + +#include "vswitch-idl.h" + +void reconfigure_datapath(const struct ovsrec_open_vswitch *, + unsigned int idl_seqno); +void destroy_all_datapaths(void); + +#endif /* datapath-config.h */ diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 2976771aeaba..e8ac24a50ff2 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -26,6 +26,7 @@ #include "connectivity.h" #include "coverage.h" #include "daemon.h" +#include "datapath-config.h" #include "dirs.h" #include "dpif.h" #include "dpdk.h" @@ -508,6 +509,7 @@ bridge_exit(bool delete_datapath) HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) { bridge_destroy(br, delete_datapath); } + destroy_all_datapaths(); ovsdb_idl_destroy(idl); } @@ -669,6 +671,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) } reconfigure_system_stats(ovs_cfg); + reconfigure_datapath(ovs_cfg, idl_seqno); /* Complete the configuration. */ sflow_bridge_number = 0; From patchwork Thu Jul 25 23:24:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137168 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="A9clq+gP"; 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 45vpMd5PpHz9s4Y for ; Fri, 26 Jul 2019 09:29:33 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4D29CD8E; Thu, 25 Jul 2019 23:24: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 66DA7D7A for ; Thu, 25 Jul 2019 23:24:40 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C350B224 for ; Thu, 25 Jul 2019 23:24:39 +0000 (UTC) Received: by mail-pg1-f193.google.com with SMTP id f25so23768754pgv.10 for ; Thu, 25 Jul 2019 16:24:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vYyOv9LeG+eMK8FutP1Db6ZUI1hUlwVWyBLcAhVfMis=; b=A9clq+gPAj+T0hKhfDV//oHs6w7lo8GifFdhQSyu+omcbCo803SKHCkehQhOJ/Pb5w usdyoHGCDTOLu/UnOVh2m52aVnhLxO0igLSKvFwyE+lP99woQDKQx4NqVsVMkwSPrrFv OyEYHVgezSANWfdCB/aX6VQofW7G19H51o4bWb2hVuOMS7FjAZq5qgoHdknCIalm0h4o A1+YUXAsX4ZdS6RoaZIFSyvPFPHhn79Tj9mhj2ptM1a4qTRcEdl3Ed0wbIB93PwQIkHh bgTESXCeQp/CKwxXJ+5JV4w1Zu2qJVOqqph7APg/v0Y52/gkzixOXm5GGjTSSXKrXDaa J8dA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vYyOv9LeG+eMK8FutP1Db6ZUI1hUlwVWyBLcAhVfMis=; b=LxJXmmjuhyp55iVaBL6/F2BuCeeePE3SFgv5qsSFArXEsZSnbSAMbpYfdy3zuI1jJX /BCcae5ls2l0P6CaMUHCHT1CuwDZBN15YNE2ZR0ffbZ5gUsCKMB8BajaSoXKCEZMM41f +hCIa36VssKZBz37iNdDltIdlp3VkoVFlxehy0TGqviniweTug7dCT/HGVbjmAGlGfSd m2eQe0IrTW0W7T7khNnUjWSib5tiYiXCeuzHj9uVjlb0+6lge9CG1l/Bja5eTsGBk/r6 +qlRpe0OH6hp9gJ1tBfNi/42lKZ0DWhZDSgNTqhQ6TbuB0swnPh/EBeW1akhRhTSnEyG UMxw== X-Gm-Message-State: APjAAAWOH+W/RsQGytMM/UW3LXwwk/d7+k7bxm/qQYXAopzehYHYmb/w ZGVfVQF5z/XTWzYdwapS6MvyzaNQ X-Google-Smtp-Source: APXvYqwb9v0pLvX8IU7gaRoT1pLTddclaRHmMJR5EvC//brj7pMFodOADbLgfqeEFWqejJgF6RHJ0Q== X-Received: by 2002:aa7:8e10:: with SMTP id c16mr18587711pfr.124.1564097078861; Thu, 25 Jul 2019 16:24:38 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:37 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:11 -0700 Message-Id: <1564097054-72663-10-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 09/12] datapath: compat: Backport nf_conntrack_timeout support 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 This patch brings in nf_ct_timeout_put() and nf_ct_set_timeout() when it is not available in the kernel. Three symbols are created in acinclude.m4. * HAVE_NF_CT_SET_TIMEOUT is used to determine if upstream net-next commit 717700d183d65 ("netfilter: Export nf_ct_{set,destroy}_timeout()") is availabe. If it is defined, the kernel should have all the nf_conntrack_timeout support that OVS needs. * HAVE_NF_CT_TIMEOUT is used to check if upstream net-next commit 6c1fd7dc489d9 ("netfilter: cttimeout: decouple timeout policy from nfnetlink_cttimeout object") is there. If it is not defined, we will use the old ctnl_timeout interface rather than the nf_ct_timeout interface that is introduced in this commit. * HAVE_NF_CT_TIMEOUT_FIND_GET_HOOK_NET is used to check if upstream commit 19576c9478682 ("netfilter: cttimeout: add netns support") is there, so that we pass different arguement based on whether the kernel has netns support. Signed-off-by: Yi-Hung Wei Acked-by: William Tu --- acinclude.m4 | 7 ++ datapath/linux/Modules.mk | 2 + .../include/net/netfilter/nf_conntrack_timeout.h | 34 +++++++ datapath/linux/compat/nf_conntrack_timeout.c | 102 +++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h create mode 100644 datapath/linux/compat/nf_conntrack_timeout.c diff --git a/acinclude.m4 b/acinclude.m4 index 9e1569b07c73..396b5f412094 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -707,6 +707,13 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_seqadj.h], [nf_ct_seq_adjust]) OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_count.h], [nf_conncount_gc_list], [OVS_DEFINE([HAVE_UPSTREAM_NF_CONNCOUNT])]) + OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_timeout.h], [nf_ct_set_timeout]) + OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_timeout.h], [struct nf_ct_timeout], + [OVS_DEFINE([HAVE_NF_CT_TIMEOUT])]) + OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_timeout.h], + [\(*nf_ct_timeout_find_get_hook\)], [net], + [OVS_DEFINE([HAVE_NF_CT_TIMEOUT_FIND_GET_HOOK_NET])]) + OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32]) OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32_max]) diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk index cbb29f1c69d0..f93097b8e0e5 100644 --- a/datapath/linux/Modules.mk +++ b/datapath/linux/Modules.mk @@ -21,6 +21,7 @@ openvswitch_sources += \ linux/compat/nf_conntrack_core.c \ linux/compat/nf_conntrack_proto.c \ linux/compat/nf_conntrack_reasm.c \ + linux/compat/nf_conntrack_timeout.c \ linux/compat/reciprocal_div.c \ linux/compat/skbuff-openvswitch.c \ linux/compat/socket.c \ @@ -108,6 +109,7 @@ openvswitch_headers += \ linux/compat/include/net/netfilter/nf_conntrack_helper.h \ linux/compat/include/net/netfilter/nf_conntrack_labels.h \ linux/compat/include/net/netfilter/nf_conntrack_seqadj.h \ + linux/compat/include/net/netfilter/nf_conntrack_timeout.h \ linux/compat/include/net/netfilter/nf_conntrack_zones.h \ linux/compat/include/net/netfilter/nf_nat.h \ linux/compat/include/net/netfilter/ipv6/nf_defrag_ipv6.h \ diff --git a/datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h b/datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h new file mode 100644 index 000000000000..134e72b8363e --- /dev/null +++ b/datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h @@ -0,0 +1,34 @@ +#ifndef _NF_CONNTRACK_TIMEOUT_WRAPPER_H +#define _NF_CONNTRACK_TIMEOUT_WRAPPER_H + +#include_next + +#ifndef HAVE_NF_CT_SET_TIMEOUT + +#ifndef HAVE_NF_CT_TIMEOUT +#define nf_ct_timeout ctnl_timeout +#endif + +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT +int rpl_nf_ct_set_timeout(struct net *net, struct nf_conn *ct, u8 l3num, u8 l4num, + const char *timeout_name); +void rpl_nf_ct_destroy_timeout(struct nf_conn *ct); +#else +static inline int rpl_nf_ct_set_timeout(struct net *net, struct nf_conn *ct, + u8 l3num, u8 l4num, + const char *timeout_name) +{ + return -EOPNOTSUPP; +} + +static inline void rpl_nf_ct_destroy_timeout(struct nf_conn *ct) +{ + return; +} +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ + +#define nf_ct_set_timeout rpl_nf_ct_set_timeout +#define nf_ct_destroy_timeout rpl_nf_ct_destroy_timeout + +#endif /* HAVE_NF_CT_SET_TIMEOUT */ +#endif /* _NF_CONNTRACK_TIMEOUT_WRAPPER_H */ diff --git a/datapath/linux/compat/nf_conntrack_timeout.c b/datapath/linux/compat/nf_conntrack_timeout.c new file mode 100644 index 000000000000..c02baff5771b --- /dev/null +++ b/datapath/linux/compat/nf_conntrack_timeout.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT +#ifndef HAVE_NF_CT_SET_TIMEOUT +static void rpl__nf_ct_timeout_put(struct nf_ct_timeout *timeout) +{ + typeof(nf_ct_timeout_put_hook) timeout_put; + + timeout_put = rcu_dereference(nf_ct_timeout_put_hook); + if (timeout_put) + timeout_put(timeout); +} + +int rpl_nf_ct_set_timeout(struct net *net, struct nf_conn *ct, + u8 l3num, u8 l4num, const char *timeout_name) +{ + typeof(nf_ct_timeout_find_get_hook) timeout_find_get; + struct nf_ct_timeout *timeout; + struct nf_conn_timeout *timeout_ext; + const char *errmsg = NULL; + int ret = 0; + + rcu_read_lock(); + timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook); + if (!timeout_find_get) { + ret = -ENOENT; + errmsg = "Timeout policy base is empty"; + goto out; + } + +#ifdef HAVE_NF_CT_TIMEOUT_FIND_GET_HOOK_NET + timeout = timeout_find_get(net, timeout_name); +#else + timeout = timeout_find_get(timeout_name); +#endif + if (!timeout) { + ret = -ENOENT; + pr_info_ratelimited("No such timeout policy \"%s\"\n", + timeout_name); + goto out; + } + + if (timeout->l3num != l3num) { + ret = -EINVAL; + pr_info_ratelimited("Timeout policy `%s' can only be used by " + "L%d protocol number %d\n", + timeout_name, 3, timeout->l3num); + goto err_put_timeout; + } + /* Make sure the timeout policy matches any existing protocol tracker, + * otherwise default to generic. + */ + if (timeout->l4proto->l4proto != l4num) { + ret = -EINVAL; + pr_info_ratelimited("Timeout policy `%s' can only be used by " + "L%d protocol number %d\n", + timeout_name, 4, timeout->l4proto->l4proto); + goto err_put_timeout; + } + timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC); + if (!timeout_ext) { + ret = -ENOMEM; + goto err_put_timeout; + } + + rcu_read_unlock(); + return ret; + +err_put_timeout: + rpl__nf_ct_timeout_put(timeout); +out: + rcu_read_unlock(); + if (errmsg) + pr_info_ratelimited("%s\n", errmsg); + return ret; +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_set_timeout); + +void rpl_nf_ct_destroy_timeout(struct nf_conn *ct) +{ + struct nf_conn_timeout *timeout_ext; + typeof(nf_ct_timeout_put_hook) timeout_put; + + rcu_read_lock(); + timeout_put = rcu_dereference(nf_ct_timeout_put_hook); + + if (timeout_put) { + timeout_ext = nf_ct_timeout_find(ct); + if (timeout_ext) { + timeout_put(timeout_ext->timeout); + RCU_INIT_POINTER(timeout_ext->timeout, NULL); + } + } + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_destroy_timeout); + +#endif /* HAVE_NF_CT_SET_TIMEOUT */ +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ From patchwork Thu Jul 25 23:24:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137169 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="TJs5VRcd"; 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 45vpN538vfz9s4Y for ; Fri, 26 Jul 2019 09:29:57 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 03945D93; Thu, 25 Jul 2019 23:24:44 +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 A3750D7F for ; Thu, 25 Jul 2019 23:24:42 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f176.google.com (mail-pg1-f176.google.com [209.85.215.176]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 70411B0 for ; Thu, 25 Jul 2019 23:24:41 +0000 (UTC) Received: by mail-pg1-f176.google.com with SMTP id f5so14958997pgu.5 for ; Thu, 25 Jul 2019 16:24:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=A8L9182TgerUr6TVkr6ePfyOinwZJ2JU6eS/zvKBuL8=; b=TJs5VRcdcvNeTxhuakOIv51sBeRM/2Thi13qx6YkyePnxi28Ms+nBbiAhm87LRHpkr A35A+M/syzhc0OG6IwnKoh0Tt525zo1cI6VzBW+XS7d8efEFjeRup9ox9O2wvKpsOEg+ bjnodyf2m66tAXejwMa8L4TfiAIqGoUq2Y+NhKAkdFysRO0Ggk+OA5yd1xqQ3qYACP6+ SqDKmTPVqcVIH1y+EuV44VK2umfVp0YmJBik2F1j0WQHdVguVYqMxMAO6HTOKAEzalol 27plfy5/rcoLTz+QYAFhrYa9aXMTqidzYt3AqbvF7InNvo7K7EfSMtCoMXjgqfNeQB7V wKxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=A8L9182TgerUr6TVkr6ePfyOinwZJ2JU6eS/zvKBuL8=; b=m9ZINC9ToObQ3FZu+h9+1JMCRePeMT46ogIKiXi60M8+2bxE3sqXxE/uVCMk4yS0uT m2/DoOg3LqUPJ0+zgiSMuS2uqa02PFHLtISJQ2w4MLsgtKQzdeJ3baVUGnNK4fS26Njb AGYV7qQK7IDUgOL7cSLJcaHjuOTLh50pLFg4WmAA2QVK52/K3huvJYp9UK2uUtYlLxi9 3PbiEOGhV3UnADr8iro+7AqYhi3hG0xk+4f7HvQK/MXFtaWwEqe+fOKJbFyzdh+1NISe k97EEVJ1pnVeGls4lQekx0JzsEKeYjO/ePrEN2K3mU5WGNzgxOaFAgt6eArixWLXPW/E s+4g== X-Gm-Message-State: APjAAAV89PKHWg5oCkrSRkZ0uaBL6f3HKSOE8mVb1CRCh+M0polugoGL AZapBQoHAUW8tUjJWtun4fDGwapd X-Google-Smtp-Source: APXvYqxY3JclNOHBE3qPkUVfCgRa2p+ANDPPbEOt2CMlmkhzxI8WkUyetCEP9J1eMuCNHHdM7ckqwA== X-Received: by 2002:a63:db47:: with SMTP id x7mr87890751pgi.375.1564097080424; Thu, 25 Jul 2019 16:24:40 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:39 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:12 -0700 Message-Id: <1564097054-72663-11-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 10/12] datapath: Add support for conntrack timeout policy 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 This patch adds support for specifying a timeout policy for a connection in connection tracking system in kernel datapath. The timeout policy will be attached to a connection when the connection is committed to conntrack. This patch introduces a new odp field OVS_CT_ATTR_TIMEOUT in the ct action that specifies the timeout policy in the datapath. In the following patch, during the upcall process, the vswitchd will use the ct_zone to look up the corresponding timeout policy and fill OVS_CT_ATTR_TIMEOUT if it is available. The datapath code is from the following two net-next upstream commits. Upstream commit: commit 06bd2bdf19d2f3d22731625e1a47fa1dff5ac407 Author: Yi-Hung Wei Date: Tue Mar 26 11:31:14 2019 -0700 openvswitch: Add timeout support to ct action Add support for fine-grain timeout support to conntrack action. The new OVS_CT_ATTR_TIMEOUT attribute of the conntrack action specifies a timeout to be associated with this connection. If no timeout is specified, it acts as is, that is the default timeout for the connection will be automatically applied. Example usage: $ nfct timeout add timeout_1 inet tcp syn_sent 100 established 200 $ ovs-ofctl add-flow br0 in_port=1,ip,tcp,action=ct(commit,timeout=timeout_1) CC: Pravin Shelar CC: Pablo Neira Ayuso Signed-off-by: Yi-Hung Wei Acked-by: Pravin B Shelar Signed-off-by: David S. Miller commit 6d670497e01803b486aa72cc1a718401ab986896 Author: Dan Carpenter Date: Tue Apr 2 09:53:14 2019 +0300 openvswitch: use after free in __ovs_ct_free_action() We free "ct_info->ct" and then use it on the next line when we pass it to nf_ct_destroy_timeout(). This patch swaps the order to avoid the use after free. Fixes: 06bd2bdf19d2 ("openvswitch: Add timeout support to ct action") Signed-off-by: Dan Carpenter Acked-by: Yi-Hung Wei Signed-off-by: David S. Miller Signed-off-by: Yi-Hung Wei --- datapath/conntrack.c | 30 ++++++++++++++++++++++- datapath/linux/compat/include/linux/openvswitch.h | 4 +++ lib/dpif-netdev.c | 4 +++ lib/odp-util.c | 29 +++++++++++++++++++--- tests/odp.at | 1 + 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/datapath/conntrack.c b/datapath/conntrack.c index 292febb3c83e..f85d0a2572f6 100644 --- a/datapath/conntrack.c +++ b/datapath/conntrack.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,7 @@ struct ovs_conntrack_info { u32 eventmask; /* Mask of 1 << IPCT_*. */ struct md_mark mark; struct md_labels labels; + char timeout[CTNL_TIMEOUT_NAME_MAX]; #ifdef CONFIG_NF_NAT_NEEDED struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */ #endif @@ -1519,6 +1521,8 @@ static const struct ovs_ct_len_tbl ovs_ct_attr_lens[OVS_CT_ATTR_MAX + 1] = { #endif [OVS_CT_ATTR_EVENTMASK] = { .minlen = sizeof(u32), .maxlen = sizeof(u32) }, + [OVS_CT_ATTR_TIMEOUT] = { .minlen = 1, + .maxlen = CTNL_TIMEOUT_NAME_MAX }, }; static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, @@ -1604,6 +1608,15 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, info->have_eventmask = true; info->eventmask = nla_get_u32(a); break; +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + case OVS_CT_ATTR_TIMEOUT: + memcpy(info->timeout, nla_data(a), nla_len(a)); + if (!memchr(info->timeout, '\0', nla_len(a))) { + OVS_NLERR(log, "Invalid conntrack helper"); + return -EINVAL; + } + break; +#endif default: OVS_NLERR(log, "Unknown conntrack attr (%d)", @@ -1685,6 +1698,14 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr, OVS_NLERR(log, "Failed to allocate conntrack template"); return -ENOMEM; } + + if (ct_info.timeout[0]) { + if (nf_ct_set_timeout(net, ct_info.ct, family, key->ip.proto, + ct_info.timeout)) + pr_info_ratelimited("Failed to associated timeout " + "policy `%s'\n", ct_info.timeout); + } + if (helper) { err = ovs_ct_add_helper(&ct_info, helper, key, log); if (err) @@ -1809,6 +1830,10 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info, if (ct_info->have_eventmask && nla_put_u32(skb, OVS_CT_ATTR_EVENTMASK, ct_info->eventmask)) return -EMSGSIZE; + if (ct_info->timeout[0]) { + if (nla_put_string(skb, OVS_CT_ATTR_TIMEOUT, ct_info->timeout)) + return -EMSGSIZE; + } #ifdef CONFIG_NF_NAT_NEEDED if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb)) @@ -1830,8 +1855,11 @@ static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info) { if (ct_info->helper) nf_conntrack_helper_put(ct_info->helper); - if (ct_info->ct) + if (ct_info->ct) { + if (ct_info->timeout[0]) + nf_ct_destroy_timeout(ct_info->ct); nf_ct_tmpl_free(ct_info->ct); + } } #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h index 65a003a62cf5..7b16b1d5bfe0 100644 --- a/datapath/linux/compat/include/linux/openvswitch.h +++ b/datapath/linux/compat/include/linux/openvswitch.h @@ -801,6 +801,7 @@ struct ovs_action_push_tnl { * be received on NFNLGRP_CONNTRACK_NEW and NFNLGRP_CONNTRACK_DESTROY groups, * respectively. Remaining bits control the changes for which an event is * delivered on the NFNLGRP_CONNTRACK_UPDATE group. + * @OVS_CT_ATTR_TIMEOUT: Variable length string defining conntrack timeout. */ enum ovs_ct_attr { OVS_CT_ATTR_UNSPEC, @@ -813,6 +814,9 @@ enum ovs_ct_attr { OVS_CT_ATTR_NAT, /* Nested OVS_NAT_ATTR_* */ OVS_CT_ATTR_FORCE_COMMIT, /* No argument */ OVS_CT_ATTR_EVENTMASK, /* u32 mask of IPCT_* events. */ + OVS_CT_ATTR_TIMEOUT, /* Associate timeout with this connection for + * fine-grain timeout tuning. */ + __OVS_CT_ATTR_MAX }; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2079e368fb52..7240a3e6f3c8 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7204,6 +7204,10 @@ dp_execute_cb(void *aux_, struct dp_packet_batch *packets_, /* Silently ignored, as userspace datapath does not generate * netlink events. */ break; + case OVS_CT_ATTR_TIMEOUT: + /* Userspace datapath does not support customized timeout + * policy yet. */ + break; case OVS_CT_ATTR_NAT: { const struct nlattr *b_nest; unsigned int left_nest; diff --git a/lib/odp-util.c b/lib/odp-util.c index 84ea4c148f11..28c3209031ce 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -930,6 +930,8 @@ static const struct nl_policy ovs_conntrack_policy[] = { [OVS_CT_ATTR_HELPER] = { .type = NL_A_STRING, .optional = true, .min_len = 1, .max_len = 16 }, [OVS_CT_ATTR_NAT] = { .type = NL_A_UNSPEC, .optional = true }, + [OVS_CT_ATTR_TIMEOUT] = { .type = NL_A_STRING, .optional = true, + .min_len = 1, .max_len = 32 }, }; static void @@ -941,7 +943,7 @@ format_odp_conntrack_action(struct ds *ds, const struct nlattr *attr) ovs_32aligned_u128 mask; } *label; const uint32_t *mark; - const char *helper; + const char *helper, *timeout; uint16_t zone; bool commit, force; const struct nlattr *nat; @@ -957,10 +959,12 @@ format_odp_conntrack_action(struct ds *ds, const struct nlattr *attr) mark = a[OVS_CT_ATTR_MARK] ? nl_attr_get(a[OVS_CT_ATTR_MARK]) : NULL; label = a[OVS_CT_ATTR_LABELS] ? nl_attr_get(a[OVS_CT_ATTR_LABELS]): NULL; helper = a[OVS_CT_ATTR_HELPER] ? nl_attr_get(a[OVS_CT_ATTR_HELPER]) : NULL; + timeout = a[OVS_CT_ATTR_TIMEOUT] ? + nl_attr_get(a[OVS_CT_ATTR_TIMEOUT]) : NULL; nat = a[OVS_CT_ATTR_NAT]; ds_put_format(ds, "ct"); - if (commit || force || zone || mark || label || helper || nat) { + if (commit || force || zone || mark || label || helper || timeout || nat) { ds_put_cstr(ds, "("); if (commit) { ds_put_format(ds, "commit,"); @@ -983,6 +987,9 @@ format_odp_conntrack_action(struct ds *ds, const struct nlattr *attr) if (helper) { ds_put_format(ds, "helper=%s,", helper); } + if (timeout) { + ds_put_format(ds, "timeout=%s", timeout); + } if (nat) { format_odp_ct_nat(ds, nat); } @@ -1909,8 +1916,8 @@ parse_conntrack_action(const char *s_, struct ofpbuf *actions) const char *s = s_; if (ovs_scan(s, "ct")) { - const char *helper = NULL; - size_t helper_len = 0; + const char *helper = NULL, *timeout = NULL; + size_t helper_len = 0, timeout_len = 0; bool commit = false; bool force_commit = false; uint16_t zone = 0; @@ -1987,6 +1994,16 @@ find_end: s += helper_len; continue; } + if (ovs_scan(s, "timeout=%n", &n)) { + s += n; + timeout_len = strcspn(s, delimiters_end); + if (!timeout_len || timeout_len > 31) { + return -EINVAL; + } + timeout = s; + s += timeout_len; + continue; + } n = scan_ct_nat(s, &nat_params); if (n > 0) { @@ -2027,6 +2044,10 @@ find_end: nl_msg_put_string__(actions, OVS_CT_ATTR_HELPER, helper, helper_len); } + if (timeout) { + nl_msg_put_string__(actions, OVS_CT_ATTR_TIMEOUT, timeout, + timeout_len); + } if (have_nat) { nl_msg_put_ct_nat(&nat_params, actions); } diff --git a/tests/odp.at b/tests/odp.at index 8e4ba4615548..3ab9ad62dda2 100644 --- a/tests/odp.at +++ b/tests/odp.at @@ -345,6 +345,7 @@ ct(commit,mark=0xa0a0a0a0/0xfefefefe) ct(commit,label=0x1234567890abcdef1234567890abcdef/0xf1f2f3f4f5f6f7f8f9f0fafbfcfdfeff) ct(commit,helper=ftp) ct(commit,helper=tftp) +ct(commit,timeout=ovs_tp_1_tcp4) ct(nat) ct(commit,nat(src)) ct(commit,nat(dst)) From patchwork Thu Jul 25 23:24:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137170 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="bqEOEDcL"; 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 45vpNv3ZwFz9s4Y for ; Fri, 26 Jul 2019 09:30:39 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 31FC6D98; Thu, 25 Jul 2019 23:24:46 +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 DBB99D89 for ; Thu, 25 Jul 2019 23:24:43 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id E911E893 for ; Thu, 25 Jul 2019 23:24:42 +0000 (UTC) Received: by mail-pg1-f180.google.com with SMTP id s1so17473072pgr.2 for ; Thu, 25 Jul 2019 16:24:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IihHJ8RgAHzVI+INYIMP6zQDa9UJghhoBpT0r+sTSak=; b=bqEOEDcLT+R+8njW+mLT3vCjAGWBj9ot2WO48ce9+Vwc21Yww0X2zJmqvvuLmFqJ6j Fr8uZ0shS52JELOHzntj6kg9DRJ/c2K2xtcvJ8LmBuRiigAjC78Hh6TU/cTOdE0VPXKj 9suZ96IyPNkBt/gbb2HEmgIkRPRFnQ5BO3cC5kOY3iiA/kiqu/rRI91dj9ahh8CvsffA H/47WCzcPx2rKmFvcIRwFb7ULdQjnjCP2qxWxLNfdOElWXDJpNg2oOGLgP+yJX22wy1+ LXpHy7dSsLBuF8uIhcmrqVB8blGvxqhQCLVDQ1NBB9K3CqJLiRDeAQyTpwckAooiLXvj XVBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IihHJ8RgAHzVI+INYIMP6zQDa9UJghhoBpT0r+sTSak=; b=FnL+PY8Cl70BVG8CkostAmSXwruuKWaVWdCGx5M9iJEUfThrd/5H8fHbkX9BRgJMmW dsNcfpgDNFPk9YEcHvfcWV1rAb/jfS3FzrGwfFCUdw5HQgrUH+Jp96YbOQ2om6+GFTib NLuf2lHrZucwXu4ONvamu568smlbaja502SM92jV7loW4xPYtsuEqiyA8p9Y1W4octuj nprsXqXYlr59L9RCZM9LIlER9SBifRO4yWUyebor/2YZHRBZiREBlSEsI/WC/wnqGRKx kRNITDW/1+aMZ5lpI1pcQuSd13W6+Umt6kIEtYLahsB7+SFJkPuO5XEaF+iw6S35yc5X 5w0Q== X-Gm-Message-State: APjAAAWz3Bry16/mDIJJwohDgDiRA3kG7s5NteAkuPNUgHyDeo/dOfZ8 ngZpOOMq7PL7IUaVvxFpd0tiCbQr X-Google-Smtp-Source: APXvYqydpNzSpSFqUDm2aTGqEc+cWt3jXKX3dAGvI5QQZsv3UcHOgX14kTsTGUeqSLRqfc5o3hhOkw== X-Received: by 2002:a62:27c2:: with SMTP id n185mr10584183pfn.79.1564097082079; Thu, 25 Jul 2019 16:24:42 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:40 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:13 -0700 Message-Id: <1564097054-72663-12-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 11/12] ofproto-dpif-xlate: Translate timeout policy in ct action 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 This patch derives the timeout policy based on ct zone from the internal data structure that reads the configuration from ovsdb. Signed-off-by: Yi-Hung Wei --- lib/ct-dpif.c | 10 ++++++++++ lib/ct-dpif.h | 3 +++ lib/datapath-config.c | 30 ++++++++++++++++++++++++++++++ lib/datapath-config.h | 2 ++ lib/dpif-netdev.c | 1 + lib/dpif-netlink.c | 10 ++++++++++ lib/dpif-provider.h | 5 +++++ ofproto/ofproto-dpif-xlate.c | 23 +++++++++++++++++++++++ 8 files changed, 84 insertions(+) diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index 1625754e2441..e2c96b29b17f 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -864,3 +864,13 @@ ct_dpif_timeout_policy_dump_done(struct dpif *dpif, void *state) ? dpif->dpif_class->ct_timeout_policy_dump_done(dpif, state) : EOPNOTSUPP); } + +int +ct_dpif_format_timeout_policy_name(struct dpif *dpif, uint32_t tp_id, + uint16_t dl_type, uint8_t nw_proto, + struct ds *ds) +{ + return (dpif->dpif_class->ct_format_timeout_policy_name + ? dpif->dpif_class->ct_format_timeout_policy_name( + dpif, tp_id, dl_type, nw_proto, ds) : EOPNOTSUPP); +} diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index de032cc416ce..a4e91f975a9b 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -318,5 +318,8 @@ int ct_dpif_timeout_policy_dump_start(struct dpif *dpif, void **statep); int ct_dpif_timeout_policy_dump_next(struct dpif *dpif, void *state, struct ct_dpif_timeout_policy **tp); int ct_dpif_timeout_policy_dump_done(struct dpif *dpif, void *state); +int ct_dpif_format_timeout_policy_name(struct dpif *dpif, uint32_t tp_id, + uint16_t dl_type, uint8_t nw_proto, + struct ds *ds); #endif /* CT_DPIF_H */ diff --git a/lib/datapath-config.c b/lib/datapath-config.c index cdd2128a60bc..2f3852100b78 100644 --- a/lib/datapath-config.c +++ b/lib/datapath-config.c @@ -377,3 +377,33 @@ destroy_all_datapaths(void) datapath_destroy(dp); } } + +/* If timeout policy is found in datapath '*dp_type' and in 'zone', + * sets timeout policy id in '*tp_id' and returns true. Otherwise, + * returns false. */ +bool +datapath_get_zone_timeout_policy_id(const char *dp_type, uint16_t zone, + uint32_t *tp_id) +{ + struct datapath *dp; + struct ct_zone *ct_zone; + struct ct_timeout_policy *ct_tp; + + dp = datapath_lookup(dp_type); + if (!dp) { + return false; + } + + ct_zone = ct_zone_lookup(&dp->ct_zones, zone); + if (!ct_zone) { + return false; + } + + ct_tp = ct_timeout_policy_lookup(&dp->ct_tps, &ct_zone->tp_uuid); + if (!ct_tp) { + return false; + } + + *tp_id = ct_tp->cdtp.id; + return true; +} diff --git a/lib/datapath-config.h b/lib/datapath-config.h index d9a90e4f8312..0e0cd7eaad2f 100644 --- a/lib/datapath-config.h +++ b/lib/datapath-config.h @@ -21,5 +21,7 @@ void reconfigure_datapath(const struct ovsrec_open_vswitch *, unsigned int idl_seqno); void destroy_all_datapaths(void); +bool datapath_get_zone_timeout_policy_id(const char *dp_type, uint16_t zone, + uint32_t *tp_id); #endif /* datapath-config.h */ diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 7240a3e6f3c8..19cf9f21ec85 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7539,6 +7539,7 @@ const struct dpif_class dpif_netdev_class = { NULL, /* ct_timeout_policy_dump_start */ NULL, /* ct_timeout_policy_dump_next */ NULL, /* ct_timeout_policy_dump_done */ + NULL, /* ct_format_timeout_policy_name */ dpif_netdev_ipf_set_enabled, dpif_netdev_ipf_set_min_frag, dpif_netdev_ipf_set_max_nfrags, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index abfad9543c3b..8e6f2ebb51e1 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -3076,6 +3076,15 @@ dpif_netlink_format_tp_name(uint32_t id, uint16_t l3num, uint8_t l4num, ovs_assert(tp_name->length < CTNL_TIMEOUT_NAME_MAX); } +static int +dpif_netlink_ct_format_timeout_policy_name(struct dpif *dpif OVS_UNUSED, + uint32_t tp_id, uint16_t dl_type, uint8_t nw_proto, struct ds *ds) +{ + dpif_netlink_format_tp_name(tp_id, + dl_type == ETH_TYPE_IP ? AF_INET : AF_INET6, nw_proto, ds); + return 0; +} + #define CT_DPIF_TO_NL_TP_TCP_MAPPINGS \ CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, SYN_SENT, SYN_SENT) \ CT_DPIF_TO_NL_TP_MAPPING(TCP, TCP, SYN_RECV, SYN_RECV) \ @@ -3860,6 +3869,7 @@ const struct dpif_class dpif_netlink_class = { dpif_netlink_ct_timeout_policy_dump_start, dpif_netlink_ct_timeout_policy_dump_next, dpif_netlink_ct_timeout_policy_dump_done, + dpif_netlink_ct_format_timeout_policy_name, NULL, /* ipf_set_enabled */ NULL, /* ipf_set_min_frag */ NULL, /* ipf_set_max_nfrags */ diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 3460ef8aa98d..f01f3abee5ab 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -541,6 +541,11 @@ struct dpif_class { struct ct_dpif_timeout_policy **tp); int (*ct_timeout_policy_dump_done)(struct dpif *, void *state); + /* Get timeout policy name (OVS_CT_ATTR_TIMEOUT) from datapath. */ + int (*ct_format_timeout_policy_name)(struct dpif *, uint32_t tp_id, + uint16_t dl_type, uint8_t nw_proto, + struct ds *ds); + /* IP Fragmentation. */ /* Disables or enables conntrack fragment reassembly. The default diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 28a7fdd842a6..12fa9684d0e4 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -28,10 +28,12 @@ #include "bond.h" #include "bundle.h" #include "byte-order.h" +#include "ct-dpif.h" #include "cfm.h" #include "connmgr.h" #include "coverage.h" #include "csum.h" +#include "datapath-config.h" #include "dp-packet.h" #include "dpif.h" #include "in-band.h" @@ -5977,6 +5979,25 @@ put_ct_helper(struct xlate_ctx *ctx, } static void +put_ct_timeout(struct ofpbuf *odp_actions, const char *dp_type, + struct dpif *dpif, const struct flow *flow, + struct flow_wildcards *wc, uint16_t zone_id) +{ + uint32_t tp_id; + + if (datapath_get_zone_timeout_policy_id(dp_type, zone_id, &tp_id)) { + struct ds ds = DS_EMPTY_INITIALIZER; + int err = ct_dpif_format_timeout_policy_name( + dpif, tp_id, ntohs(flow->dl_type), flow->nw_proto, &ds); + if (!err) { + memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); + nl_msg_put_string(odp_actions, OVS_CT_ATTR_TIMEOUT, ds_cstr(&ds)); + } + ds_destroy(&ds); + } +} + +static void put_ct_nat(struct xlate_ctx *ctx) { struct ofpact_nat *ofn = ctx->ct_nat_action; @@ -6071,6 +6092,8 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, put_ct_mark(&ctx->xin->flow, ctx->odp_actions, ctx->wc); put_ct_label(&ctx->xin->flow, ctx->odp_actions, ctx->wc); put_ct_helper(ctx, ctx->odp_actions, ofc); + put_ct_timeout(ctx->odp_actions, ctx->xbridge->ofproto->backer->type, + ctx->xbridge->dpif, &ctx->xin->flow, ctx->wc, zone); put_ct_nat(ctx); ctx->ct_nat_action = NULL; nl_msg_end_nested(ctx->odp_actions, ct_offset); From patchwork Thu Jul 25 23:24:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1137171 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="T/qlfavh"; 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 45vpPN5gPZz9s4Y for ; Fri, 26 Jul 2019 09:31:04 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 03121DB4; Thu, 25 Jul 2019 23:24:47 +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 62C86D98 for ; Thu, 25 Jul 2019 23:24:45 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 63570893 for ; Thu, 25 Jul 2019 23:24:44 +0000 (UTC) Received: by mail-pf1-f195.google.com with SMTP id t16so23473949pfe.11 for ; Thu, 25 Jul 2019 16:24:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RtLN9kEOuMPVav1h8kEwEIXHGIbH0YjKlE//dLEcItc=; b=T/qlfavhN6Uf2O0yZZfkwD7kr38Vm2Ixiq5kvq7HGv+UBf8kbt/QVfDiGHybcfq0NO YBW2Gf0aA3TkMIuvzqMJspXHxGx76n2zinOBNmPqei+ULLSK+hAY+OARIW1cO3se8Mqt vwurMSVSeCrfHvPUa6xOFOT/ub1gq2ZE+JnGAKd3lyg+sTr1QG/cu7+1Gkoz31/pN3tF k61qG78H3m4Htwo8mUYoypsCFX1JJOSW/Q+SovT8fmTBDZH8kUkQsDk8VLu7VAriXk09 ucK3JTdUq3quEanBoLYytTQY0/JJlyXXZOD4aFjA2+lRb3bA5GiyE8Gc9PGfBLlA4N0G aaTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RtLN9kEOuMPVav1h8kEwEIXHGIbH0YjKlE//dLEcItc=; b=BPM1hwQRXzqbkJF6MdbstzVoY9BO0Xj3MrZaaWO0pEfFrIE3fjtiEZLPzLWLXpEIoP RaWsg7voF5nC5Xd30LDB8YxRU8EDlGwUY8cGAINhpp0YG5tGxFC9J1MRxfyusdRREOow i6bVBaGedDEr/EeC2yp+0UXQ8AP1sFF3LIf8Wn1x7isxGypKg3SAMFpii5+dZqsk4zis lTny6kP3nyiBOe8iVFvjDYQN9lAwP99HjVIp6k0UU31CtQEfGdMmY8VKzUISdbfdbjSy 7kPWtva67LVM1TzTjncJc16q9qho5YZFRgcCWtI1rU3SbF74nNwGqQzP7YyDLkTti+b0 ILlg== X-Gm-Message-State: APjAAAXgQ0ab8/rBQpsfE2Zqdw06UGBUsyexgfzVnhaxnMyFipa4kL+E j5xi5NnIFboEkJI2BaaF+y+93bNA X-Google-Smtp-Source: APXvYqz8Nh7aQpBQLv9asXlWZ9ZSm+jbtEI0QK7uNrSUVcXApVN6D2IToW3tIzNgv18hZ0+Rj4zuFA== X-Received: by 2002:a63:8ac3:: with SMTP id y186mr88035132pgd.13.1564097083522; Thu, 25 Jul 2019 16:24:43 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id x9sm28189940pgp.75.2019.07.25.16.24.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 25 Jul 2019 16:24:42 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org, blp@ovn.org Date: Thu, 25 Jul 2019 16:24:14 -0700 Message-Id: <1564097054-72663-13-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> References: <1564097054-72663-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 12/12] system-traffic: Add zone-based conntrack timeout policy test 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 This patch adds a system traffic test to verify the zone-based conntrack timeout feature. The test uses ovs-vsctl commands to configure the customized ICMP and UDP timeout on zone 5 to a shorter period. It then injects ICMP and UDP traffic to conntrack, and checks if the corresponding conntrack entry expires after the predefined timeout. Signed-off-by: Yi-Hung Wei --- tests/system-kmod-macros.at | 9 ++++++ tests/system-traffic.at | 65 ++++++++++++++++++++++++++++++++++++++++ tests/system-userspace-macros.at | 10 +++++++ 3 files changed, 84 insertions(+) diff --git a/tests/system-kmod-macros.at b/tests/system-kmod-macros.at index 554a61e9bd95..f3c68277be65 100644 --- a/tests/system-kmod-macros.at +++ b/tests/system-kmod-macros.at @@ -100,6 +100,15 @@ m4_define([CHECK_CONNTRACK_FRAG_OVERLAP], # m4_define([CHECK_CONNTRACK_NAT]) +# CHECK_CONNTRACK_TIMEOUT() +# +# Perform requirements checks for running conntrack customized timeout tests. +# +m4_define([CHECK_CONNTRACK_TIMEOUT], +[ + AT_SKIP_IF([! cat /boot/config-$(uname -r) | grep NF_CONNTRACK_TIMEOUT | grep '=y' > /dev/null]) +]) + # CHECK_CT_DPIF_PER_ZONE_LIMIT() # # Perform requirements checks for running ovs-dpctl ct-[set|get|del]-limits per diff --git a/tests/system-traffic.at b/tests/system-traffic.at index 1a04199dcfe9..6699466dbf4f 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -3179,6 +3179,71 @@ NXST_FLOW reply: OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([conntrack - zone-based timeout policy]) +CHECK_CONNTRACK() +CHECK_CONNTRACK_TIMEOUT() +OVS_TRAFFIC_VSWITCHD_START() + +ADD_NAMESPACES(at_ns0, at_ns1) + +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") + +AT_DATA([flows.txt], [dnl +priority=1,action=drop +priority=10,arp,action=normal +priority=100,in_port=1,ip,action=ct(zone=5, table=1) +priority=100,in_port=2,ip,action=ct(zone=5, table=1) +table=1,in_port=2,ip,ct_state=+trk+est,action=1 +table=1,in_port=1,ip,ct_state=+trk+new,action=ct(commit,zone=5),2 +table=1,in_port=1,ip,ct_state=+trk+est,action=2 +]) + +AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) + +dnl Add customized timeout +dnl Note that the default ICMP timeout is 30 seconds. +dnl The default timeout for unreplied UDP is 30 seconds, and +dnl 180 seconds for replied UDP connection. +AT_CHECK([ovs-vsctl add-dp system]) +AT_CHECK([ovs-vsctl add-zone-tp system zone=5 udp_first=3 icmp_first=3]) + +dnl ICMP traffic +NS_CHECK_EXEC([at_ns0], [ping -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 +]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0],[dnl +icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0),zone=5 +]) + +dnl Wait until ICMP timeout expire. +dnl We intend to wait a bit longer, because conntrack does not recycle the entry right after it is expired. +sleep 4 + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl +]) + +dnl Send out an UDP packet from port 1 +AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "dst=10\.1\.1\.2,"], [0], [dnl +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),zone=5 +]) + +dnl Wait until UDP timeout expire +sleep 4 + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl +]) + +AT_CHECK([ovs-ofctl del-flows br0]) +AT_CHECK([ovs-appctl revalidator/wait]) +AT_CHECK([ovs-vsctl del-zone-tp system zone=5]) + +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP + AT_BANNER([conntrack - L7]) AT_SETUP([conntrack - IPv4 HTTP]) diff --git a/tests/system-userspace-macros.at b/tests/system-userspace-macros.at index 9d5f3bf419d3..ceabad7499d8 100644 --- a/tests/system-userspace-macros.at +++ b/tests/system-userspace-macros.at @@ -98,6 +98,16 @@ m4_define([CHECK_CONNTRACK_FRAG_OVERLAP]) # m4_define([CHECK_CONNTRACK_NAT]) +# CHECK_CONNTRACK_TIMEOUT() +# +# Perform requirements checks for running conntrack customized timeout tests. +* The userspace datapath does not support this feature yet. +# +m4_define([CHECK_CONNTRACK_TIMEOUT], +[ + AT_SKIP_IF([:]) +]) + # CHECK_CT_DPIF_PER_ZONE_LIMIT() # # Perform requirements checks for running ovs-dpctl ct-[set|get|del]-limits per