From ffdc711411551c07af789a3dad8e846c11f19ad9 Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Mar 17 2021 00:25:31 +0000 Subject: Import openvswitch2.13-2.13.0-96 from Fast DataPath --- diff --git a/.openvswitch.metadata b/.openvswitch.metadata index 0db19ca..8e71823 100644 --- a/.openvswitch.metadata +++ b/.openvswitch.metadata @@ -1,5 +1,5 @@ -002450621b33c5690060345b0aac25bc2426d675 SOURCES/docutils-0.12.tar.gz -435b0b3a5da6d7417d318050e5b50ac400354c60 SOURCES/dpdk-19.11.tar.xz -0c5f78212173d2cac286f8f78aa95ebdea9e2444 SOURCES/openvswitch-2.13.0.tar.gz -d34f96421a86004aa5d26ecf975edefd09f948b1 SOURCES/Pygments-1.4.tar.gz -6beb30f18ffac3de7689b7fd63e9a8a7d9c8df3a SOURCES/Sphinx-1.1.3.tar.gz +002450621b33c5690060345b0aac25bc2426d675 SOURCES/docutils-0.12.tar.gz +0c5f78212173d2cac286f8f78aa95ebdea9e2444 SOURCES/openvswitch-2.13.0.tar.gz +d34f96421a86004aa5d26ecf975edefd09f948b1 SOURCES/Pygments-1.4.tar.gz +6beb30f18ffac3de7689b7fd63e9a8a7d9c8df3a SOURCES/Sphinx-1.1.3.tar.gz +435b0b3a5da6d7417d318050e5b50ac400354c60 SOURCES/dpdk-19.11.tar.xz diff --git a/SOURCES/openvswitch-2.13.0.patch b/SOURCES/openvswitch-2.13.0.patch index 6537811..23eecc4 100644 --- a/SOURCES/openvswitch-2.13.0.patch +++ b/SOURCES/openvswitch-2.13.0.patch @@ -1,6 +1,6 @@ diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh new file mode 100755 -index 0000000000..ec0b40e472 +index 0000000000..c1cf85d7d9 --- /dev/null +++ b/.ci/linux-build.sh @@ -0,0 +1,244 @@ @@ -188,7 +188,7 @@ index 0000000000..ec0b40e472 + +if [ "$DPDK" ] || [ "$DPDK_SHARED" ]; then + if [ -z "$DPDK_VER" ]; then -+ DPDK_VER="19.11.2" ++ DPDK_VER="19.11.6" + fi + install_dpdk $DPDK_VER + # Enable pdump support in OVS. @@ -224,7 +224,7 @@ index 0000000000..ec0b40e472 + configure_ovs + + export DISTCHECK_CONFIGURE_FLAGS="$OPTS" -+ if ! make distcheck CFLAGS="${CFLAGS_FOR_OVS}" \ ++ if ! make distcheck -j4 CFLAGS="${CFLAGS_FOR_OVS}" \ + TESTSUITEFLAGS=-j4 RECHECK=yes; then + # testsuite.log is necessary for debugging. + cat */_build/sub/tests/testsuite.log @@ -344,14 +344,16 @@ index 0000000000..b6447aba1b +set -ev +pip3 install --user --upgrade docutils diff --git a/.cirrus.yml b/.cirrus.yml -index 1b32f55d65..263c2cd7ed 100644 +index 1b32f55d65..2caf36b85c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml -@@ -3,7 +3,7 @@ freebsd_build_task: +@@ -2,8 +2,8 @@ freebsd_build_task: + freebsd_instance: matrix: - image_family: freebsd-12-1-snap +- image_family: freebsd-12-1-snap - image_family: freebsd-11-3-snap ++ image_family: freebsd-12-2-snap + image_family: freebsd-11-4-snap cpu: 4 memory: 8G @@ -366,7 +368,7 @@ index 1b32f55d65..263c2cd7ed 100644 configure_script: diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 -index 0000000000..fe76a866ea +index 0000000000..8849659979 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,205 @@ @@ -505,7 +507,7 @@ index 0000000000..fe76a866ea + key: ${{ env.matrix_key }}-${{ env.ci_key }} + + - name: update APT cache -+ run: sudo apt update ++ run: sudo apt update || true + - name: install common dependencies + if: matrix.deb_package == '' + run: sudo apt install -y ${{ env.dependencies }} @@ -612,7 +614,7 @@ index fe3935fca2..4c8772f63a 100644 ankur dwivedi ankurengg2003@gmail.com chen zhang 3zhangchen9211@gmail.com diff --git a/Documentation/faq/releases.rst b/Documentation/faq/releases.rst -index 6702c58a2b..41e1315a4c 100644 +index 6702c58a2b..4a0dcac495 100644 --- a/Documentation/faq/releases.rst +++ b/Documentation/faq/releases.rst @@ -67,9 +67,10 @@ Q: What Linux kernel versions does each Open vSwitch release work with? @@ -663,9 +665,9 @@ index 6702c58a2b..41e1315a4c 100644 - ============ ======= + 2.9.x 17.11.10 + 2.10.x 17.11.10 -+ 2.11.x 18.11.9 -+ 2.12.x 18.11.9 -+ 2.13.x 19.11.2 ++ 2.11.x 18.11.11 ++ 2.12.x 18.11.11 ++ 2.13.x 19.11.6 + ============ ======== Q: Are all the DPDK releases that OVS versions work with maintained? @@ -690,7 +692,7 @@ index 5a314cc60a..f2039595e7 100644 Email Subject ------------- diff --git a/Documentation/intro/install/dpdk.rst b/Documentation/intro/install/dpdk.rst -index dbf88ec43f..86ee19d4c4 100644 +index dbf88ec43f..050e5544b3 100644 --- a/Documentation/intro/install/dpdk.rst +++ b/Documentation/intro/install/dpdk.rst @@ -42,7 +42,7 @@ Build requirements @@ -698,7 +700,7 @@ index dbf88ec43f..86ee19d4c4 100644 vSwitch with DPDK will require the following: -- DPDK 19.11 -+- DPDK 19.11.2 ++- DPDK 19.11.6 - A `DPDK supported NIC`_ @@ -709,9 +711,9 @@ index dbf88ec43f..86ee19d4c4 100644 - $ wget https://fast.dpdk.org/rel/dpdk-19.11.tar.xz - $ tar xf dpdk-19.11.tar.xz - $ export DPDK_DIR=/usr/src/dpdk-19.11 -+ $ wget https://fast.dpdk.org/rel/dpdk-19.11.2.tar.xz -+ $ tar xf dpdk-19.11.2.tar.xz -+ $ export DPDK_DIR=/usr/src/dpdk-stable-19.11.2 ++ $ wget https://fast.dpdk.org/rel/dpdk-19.11.6.tar.xz ++ $ tar xf dpdk-19.11.6.tar.xz ++ $ export DPDK_DIR=/usr/src/dpdk-stable-19.11.6 $ cd $DPDK_DIR #. (Optional) Configure DPDK as a shared library @@ -744,8 +746,43 @@ index 38e52c8deb..55a98e2b0e 100644 Link State Change (LSC) detection configuration ----------------------------------------------- +diff --git a/Documentation/topics/dpdk/qos.rst b/Documentation/topics/dpdk/qos.rst +index 103495415a..a98ec672fc 100644 +--- a/Documentation/topics/dpdk/qos.rst ++++ b/Documentation/topics/dpdk/qos.rst +@@ -69,22 +69,24 @@ to prioritize certain traffic over others at a port level. + + For example, the following configuration will limit the traffic rate at a + port level to a maximum of 2000 packets a second (64 bytes IPv4 packets). +-100pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess +-Information Rate). High priority traffic is routed to queue 10, which marks ++1000pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess ++Information Rate). CIR and EIR are measured in bytes without Ethernet header. ++As a result, 1000pps means (64-byte - 14-byte) * 1000 = 50,000 in the ++configuration below. High priority traffic is routed to queue 10, which marks + all traffic as CIR, i.e. Green. All low priority traffic, queue 20, is + marked as EIR, i.e. Yellow:: + + $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \ + --id=@myqos create qos type=trtcm-policer \ +- other-config:cir=52000 other-config:cbs=2048 \ +- other-config:eir=52000 other-config:ebs=2048 \ ++ other-config:cir=50000 other-config:cbs=2048 \ ++ other-config:eir=50000 other-config:ebs=2048 \ + queues:10=@dpdk1Q10 queues:20=@dpdk1Q20 -- \ + --id=@dpdk1Q10 create queue \ +- other-config:cir=41600000 other-config:cbs=2048 \ ++ other-config:cir=100000 other-config:cbs=2048 \ + other-config:eir=0 other-config:ebs=0 -- \ + --id=@dpdk1Q20 create queue \ + other-config:cir=0 other-config:cbs=0 \ +- other-config:eir=41600000 other-config:ebs=2048 \ ++ other-config:eir=50000 other-config:ebs=2048 + + This configuration accomplishes that the high priority traffic has a + guaranteed bandwidth egressing the ports at CIR (1000pps), but it can also diff --git a/Documentation/topics/dpdk/vhost-user.rst b/Documentation/topics/dpdk/vhost-user.rst -index c6c6fd8bde..4bc5aef59d 100644 +index c6c6fd8bde..d0201151a0 100644 --- a/Documentation/topics/dpdk/vhost-user.rst +++ b/Documentation/topics/dpdk/vhost-user.rst @@ -392,9 +392,9 @@ To begin, instantiate a guest as described in :ref:`dpdk-vhost-user` or @@ -755,9 +792,9 @@ index c6c6fd8bde..4bc5aef59d 100644 - $ wget https://fast.dpdk.org/rel/dpdk-19.11.tar.xz - $ tar xf dpdk-19.11.tar.xz - $ export DPDK_DIR=/root/dpdk/dpdk-19.11 -+ $ wget https://fast.dpdk.org/rel/dpdk-19.11.2.tar.xz -+ $ tar xf dpdk-19.11.2.tar.xz -+ $ export DPDK_DIR=/root/dpdk/dpdk-stable-19.11.2 ++ $ wget https://fast.dpdk.org/rel/dpdk-19.11.6.tar.xz ++ $ tar xf dpdk-19.11.6.tar.xz ++ $ export DPDK_DIR=/root/dpdk/dpdk-stable-19.11.6 $ export DPDK_TARGET=x86_64-native-linuxapp-gcc $ export DPDK_BUILD=$DPDK_DIR/$DPDK_TARGET $ cd $DPDK_DIR @@ -900,12 +937,31 @@ index b279303d18..b3b56cd50e 100644 boot.sh \ poc/builders/Vagrantfile \ diff --git a/NEWS b/NEWS -index dab94e924d..86d6e0a3d8 100644 +index dab94e924d..32ec919d13 100644 --- a/NEWS +++ b/NEWS -@@ -1,3 +1,30 @@ -+v2.13.2 - xx xxx xxxx +@@ -1,3 +1,49 @@ ++v2.13.4 - xx xxx xxxx ++--------------------- ++ - DPDK: ++ * OVS validated with DPDK 19.11.6. It is recommended to use this version ++ until further releases. ++ - ovs-ctl: ++ * New option '--no-record-hostname' to disable hostname configuration ++ in ovsdb on startup. ++ * New command 'record-hostname-if-not-set' to update hostname in ovsdb. ++ ++v2.13.3 - 10 Feb 2021 +--------------------- ++ - Bug fixes ++ - Security: ++ * Fixed packet parsing vulnerability CVE-2020-35498. ++ ++v2.13.2 - 13 Jan 2021 ++--------------------- ++ - Bug fixes ++ - LLDP: ++ * Security fixes for CVE-2015-8011 and CVE-2020-27827. + - IPsec: + * Fixed support of strongswan 5.7+ in ovs-monitor-ipsec. + * Add option '--no-cleanup' to allow ovs-monitor-ipsec to stop without @@ -934,7 +990,7 @@ index dab94e924d..86d6e0a3d8 100644 v2.13.0 - 14 Feb 2020 --------------------- - OVN: -@@ -43,6 +70,9 @@ v2.13.0 - 14 Feb 2020 +@@ -43,6 +89,9 @@ v2.13.0 - 14 Feb 2020 - 'ovs-appctl dpctl/dump-flows' can now show offloaded=partial for partially offloaded flows, dp:dpdk for fully offloaded by dpdk, and type filter supports new filters: "dpdk" and "partially-offloaded". @@ -944,7 +1000,7 @@ index dab94e924d..86d6e0a3d8 100644 v2.12.0 - 03 Sep 2019 --------------------- -@@ -117,9 +147,6 @@ v2.12.0 - 03 Sep 2019 +@@ -117,9 +166,6 @@ v2.12.0 - 03 Sep 2019 * Add support for conntrack zone-based timeout policy. - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows. 'ovs-appctl dpctl/dump-flows' should be used instead. @@ -970,7 +1026,7 @@ index e06ddf2671..8e64d74aee 100644 :target: https://ci.appveyor.com/project/blp/ovs/history .. image:: https://api.cirrus-ci.com/github/openvswitch/ovs.svg diff --git a/acinclude.m4 b/acinclude.m4 -index c1470ccc6b..12fd6c4a51 100644 +index c1470ccc6b..f4fd56e620 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -250,6 +250,18 @@ AC_DEFUN([OVS_CHECK_LINUX_SCTP_CT], [ @@ -1000,7 +1056,24 @@ index c1470ccc6b..12fd6c4a51 100644 AC_CHECK_DECL([RTE_IBVERBS_LINK_DLOPEN], [], [dnl not found OVS_FIND_DEPENDENCY([mlx5dv_create_wq], [mlx5], [libmlx5]) OVS_FIND_DEPENDENCY([verbs_init_cq], [ibverbs], [libibverbs]) -@@ -567,9 +578,14 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ +@@ -420,6 +431,16 @@ AC_DEFUN([OVS_CHECK_DPDK], [ + if test "$DPDK_AUTO_DISCOVER" = "false"; then + OVS_LDFLAGS="$OVS_LDFLAGS -L$DPDK_LIB_DIR" + fi ++ # Stripping out possible instruction set specific configuration that DPDK ++ # forces in pkg-config since this could override user-specified options. ++ # It's enough to have -mssse3 to build with DPDK headers. ++ DPDK_INCLUDE=$(echo "$DPDK_INCLUDE" | sed 's/-march=[[^ ]]*//g') ++ # Also stripping out '-mno-avx512f'. Support for AVX512 will be disabled ++ # if OVS will detect that it's broken. OVS could be built with a ++ # completely different toolchain that correctly supports AVX512, flags ++ # forced by DPDK only breaks our feature detection mechanism and leads to ++ # build failures: https://github.com/openvswitch/ovs-issues/issues/201 ++ DPDK_INCLUDE=$(echo "$DPDK_INCLUDE" | sed 's/-mno-avx512f//g') + OVS_CFLAGS="$OVS_CFLAGS $DPDK_INCLUDE" + OVS_ENABLE_OPTION([-mssse3]) + +@@ -567,9 +588,14 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/ip6_fib.h], [rt6_get_cookie], [OVS_DEFINE([HAVE_RT6_GET_COOKIE])]) @@ -1015,7 +1088,7 @@ index c1470ccc6b..12fd6c4a51 100644 OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [ERR_CAST]) OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [IS_ERR_OR_NULL]) -@@ -765,6 +781,10 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ +@@ -765,6 +791,10 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ [prandom_u32[[\(]]], [OVS_DEFINE([HAVE_PRANDOM_U32])]) OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32_max]) @@ -1026,7 +1099,7 @@ index c1470ccc6b..12fd6c4a51 100644 OVS_GREP_IFELSE([$KSRC/include/net/rtnetlink.h], [get_link_net]) OVS_GREP_IFELSE([$KSRC/include/net/rtnetlink.h], [name_assign_type]) -@@ -918,8 +938,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ +@@ -918,8 +948,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/sock.h], [sk_no_check_tx]) OVS_GREP_IFELSE([$KSRC/include/linux/udp.h], [no_check6_tx]) @@ -1035,7 +1108,7 @@ index c1470ccc6b..12fd6c4a51 100644 OVS_FIND_PARAM_IFELSE([$KSRC/include/net/protocol.h], [udp_add_offload], [net], [OVS_DEFINE([HAVE_UDP_ADD_OFFLOAD_TAKES_NET])]) -@@ -1294,11 +1312,11 @@ AC_DEFUN([OVS_ENABLE_SPARSE], +@@ -1294,11 +1322,11 @@ AC_DEFUN([OVS_ENABLE_SPARSE], dnl OVS_CTAGS_IDENTIFIERS dnl @@ -1050,8 +1123,21 @@ index c1470ccc6b..12fd6c4a51 100644 dnl OVS_PTHREAD_SET_NAME dnl +diff --git a/build-aux/dist-docs b/build-aux/dist-docs +index f6b88ca2d0..9429702db9 100755 +--- a/build-aux/dist-docs ++++ b/build-aux/dist-docs +@@ -43,7 +43,7 @@ rm -rf $distdir + mkdir $distdir + + # Install manpages. +-${MAKE-make} install-man mandir="$abs_distdir"/man ++${MAKE-make} install-man install-man-rst mandir="$abs_distdir"/man + (cd $distdir && mv `find man -type f` . && rm -rf man) + manpages=`cd $distdir && echo *` + diff --git a/configure.ac b/configure.ac -index 92b52f6712..72aa36b443 100644 +index 92b52f6712..34276bcbe7 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,7 @@ @@ -1059,7 +1145,7 @@ index 92b52f6712..72aa36b443 100644 AC_PREREQ(2.63) -AC_INIT(openvswitch, 2.13.0, bugs@openvswitch.org) -+AC_INIT(openvswitch, 2.13.2, bugs@openvswitch.org) ++AC_INIT(openvswitch, 2.13.4, bugs@openvswitch.org) AC_CONFIG_SRCDIR([datapath/datapath.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) @@ -1537,15 +1623,27 @@ index 23118e8b63..05ccfb9288 100644 *saddr = fl6.saddr; if (use_cache) diff --git a/debian/changelog b/debian/changelog -index 8e075bc98b..d803cf10d1 100644 +index 8e075bc98b..f63d5cc46a 100644 --- a/debian/changelog +++ b/debian/changelog -@@ -1,3 +1,15 @@ +@@ -1,3 +1,27 @@ ++openvswitch (2.13.4-1) unstable; urgency=low ++ [ Open vSwitch team ] ++ * New upstream version ++ ++ -- Open vSwitch team Wed, 10 Feb 2021 16:07:28 +0100 ++ ++openvswitch (2.13.3-1) unstable; urgency=low ++ [ Open vSwitch team ] ++ * New upstream version ++ ++ -- Open vSwitch team Wed, 10 Feb 2021 16:07:28 +0100 ++ +openvswitch (2.13.2-1) unstable; urgency=low + [ Open vSwitch team ] + * New upstream version + -+ -- Open vSwitch team Thu, 30 Jul 2020 00:25:23 +0200 ++ -- Open vSwitch team Wed, 13 Jan 2021 11:26:36 -0500 + +openvswitch (2.13.1-1) unstable; urgency=low + [ Open vSwitch team] @@ -39581,6 +39679,44 @@ index d1bd4aa12a..f646a8f742 100644 }; enum { +diff --git a/lib/conntrack-icmp.c b/lib/conntrack-icmp.c +index 63246f0124..63ddd8038b 100644 +--- a/lib/conntrack-icmp.c ++++ b/lib/conntrack-icmp.c +@@ -50,10 +50,16 @@ icmp_conn_update(struct conntrack *ct, struct conn *conn_, + struct dp_packet *pkt OVS_UNUSED, bool reply, long long now) + { + struct conn_icmp *conn = conn_icmp_cast(conn_); +- conn->state = reply ? ICMPS_REPLY : ICMPS_FIRST; +- conn_update_expiration(ct, &conn->up, icmp_timeouts[conn->state], now); ++ enum ct_update_res ret = CT_UPDATE_VALID; ++ ++ if (reply && conn->state == ICMPS_FIRST) { ++ conn->state = ICMPS_REPLY; ++ } else if (conn->state == ICMPS_FIRST) { ++ ret = CT_UPDATE_VALID_NEW; ++ } + +- return CT_UPDATE_VALID; ++ conn_update_expiration(ct, &conn->up, icmp_timeouts[conn->state], now); ++ return ret; + } + + static bool +diff --git a/lib/conntrack-private.h b/lib/conntrack-private.h +index 9a8ca39101..cd6c4bfee9 100644 +--- a/lib/conntrack-private.h ++++ b/lib/conntrack-private.h +@@ -59,6 +59,9 @@ struct conn_key { + uint8_t nw_proto; + }; + ++/* Verify that nw_proto stays uint8_t as it's used to index into l4_protos[] */ ++BUILD_ASSERT_DECL(MEMBER_SIZEOF(struct conn_key, nw_proto) == sizeof(uint8_t)); ++ + /* This is used for alg expectations; an expectation is a + * context created in preparation for establishing a data + * connection. The expectation is created by the control diff --git a/lib/conntrack-tcp.c b/lib/conntrack-tcp.c index 416cb769d2..47261c7551 100644 --- a/lib/conntrack-tcp.c @@ -39595,10 +39731,51 @@ index 416cb769d2..47261c7551 100644 } diff --git a/lib/conntrack.c b/lib/conntrack.c -index ff5a89457c..bb98395cd2 100644 +index ff5a89457c..a673678fe5 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c -@@ -813,7 +813,7 @@ static void +@@ -143,12 +143,7 @@ detect_ftp_ctl_type(const struct conn_lookup_ctx *ctx, + static void + expectation_clean(struct conntrack *ct, const struct conn_key *master_key); + +-static struct ct_l4_proto *l4_protos[] = { +- [IPPROTO_TCP] = &ct_proto_tcp, +- [IPPROTO_UDP] = &ct_proto_other, +- [IPPROTO_ICMP] = &ct_proto_icmp4, +- [IPPROTO_ICMPV6] = &ct_proto_icmp6, +-}; ++static struct ct_l4_proto *l4_protos[UINT8_MAX + 1]; + + static void + handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, +@@ -296,6 +291,7 @@ ct_print_conn_info(const struct conn *c, const char *log_msg, + struct conntrack * + conntrack_init(void) + { ++ static struct ovsthread_once setup_l4_once = OVSTHREAD_ONCE_INITIALIZER; + struct conntrack *ct = xzalloc(sizeof *ct); + + ovs_rwlock_init(&ct->resources_lock); +@@ -322,6 +318,18 @@ conntrack_init(void) + ct->clean_thread = ovs_thread_create("ct_clean", clean_thread_main, ct); + ct->ipf = ipf_init(); + ++ /* Initialize the l4 protocols. */ ++ if (ovsthread_once_start(&setup_l4_once)) { ++ for (int i = 0; i < ARRAY_SIZE(l4_protos); i++) { ++ l4_protos[i] = &ct_proto_other; ++ } ++ /* IPPROTO_UDP uses ct_proto_other, so no need to initialize it. */ ++ l4_protos[IPPROTO_TCP] = &ct_proto_tcp; ++ l4_protos[IPPROTO_ICMP] = &ct_proto_icmp4; ++ l4_protos[IPPROTO_ICMPV6] = &ct_proto_icmp6; ++ ++ ovsthread_once_done(&setup_l4_once); ++ } + return ct; + } + +@@ -813,7 +821,7 @@ static void reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn) { char *tail = dp_packet_tail(pkt); @@ -39607,7 +39784,7 @@ index ff5a89457c..bb98395cd2 100644 struct conn_key inner_key; const char *inner_l4 = NULL; uint16_t orig_l3_ofs = pkt->l3_ofs; -@@ -1277,6 +1277,11 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, +@@ -1277,6 +1285,11 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, const struct nat_action_info_t *nat_action_info, ovs_be16 tp_src, ovs_be16 tp_dst, const char *helper) { @@ -39619,7 +39796,7 @@ index ff5a89457c..bb98395cd2 100644 bool create_new_conn = false; conn_key_lookup(ct, &ctx->key, ctx->hash, now, &ctx->conn, &ctx->reply); struct conn *conn = ctx->conn; -@@ -1300,9 +1305,10 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, +@@ -1300,9 +1313,10 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, conn_key_lookup(ct, &ctx->key, hash, now, &conn, &ctx->reply); if (!conn) { @@ -39632,6 +39809,30 @@ index ff5a89457c..bb98395cd2 100644 free(log_msg); return; } +@@ -1964,9 +1978,10 @@ extract_l4(struct conn_key *key, const void *data, size_t size, bool *related, + return (!related || check_l4_icmp6(key, data, size, l3, + validate_checksum)) + && extract_l4_icmp6(key, data, size, related); +- } else { +- return false; + } ++ ++ /* For all other protocols we do not have L4 keys, so keep them zero. */ ++ return true; + } + + static bool +@@ -2249,8 +2264,8 @@ nat_select_range_tuple(struct conntrack *ct, const struct conn *conn, + conn->nat_info->nat_action & NAT_ACTION_SRC_PORT + ? true : false; + union ct_addr first_addr = ct_addr; +- bool pat_enabled = conn->key.nw_proto != IPPROTO_ICMP && +- conn->key.nw_proto != IPPROTO_ICMPV6; ++ bool pat_enabled = conn->key.nw_proto == IPPROTO_TCP || ++ conn->key.nw_proto == IPPROTO_UDP; + + while (true) { + if (conn->nat_info->nat_action & NAT_ACTION_SRC) { diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 9f8991faad..45655af461 100644 --- a/lib/dp-packet.h @@ -39674,7 +39875,7 @@ index 9f8991faad..45655af461 100644 ovs_assert(pad_size <= dp_packet_size(b)); b->l2_pad_size = pad_size; diff --git a/lib/dpctl.c b/lib/dpctl.c -index db2b1f8961..09ae97f25c 100644 +index db2b1f8961..36038a13d8 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1031,7 +1031,7 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p) @@ -39686,6 +39887,27 @@ index db2b1f8961..09ae97f25c 100644 } determine_dpif_flow_dump_types(&dump_types, &dpif_dump_types); +@@ -2502,15 +2502,16 @@ static const struct dpctl_command all_commands[] = { + { "del-if", "dp iface...", 2, INT_MAX, dpctl_del_if, DP_RW }, + { "set-if", "dp iface...", 2, INT_MAX, dpctl_set_if, DP_RW }, + { "dump-dps", "", 0, 0, dpctl_dump_dps, DP_RO }, +- { "show", "[dp...]", 0, INT_MAX, dpctl_show, DP_RO }, +- { "dump-flows", "[dp] [filter=..] [type=..]", +- 0, 3, dpctl_dump_flows, DP_RO }, ++ { "show", "[-s] [dp...]", 0, INT_MAX, dpctl_show, DP_RO }, ++ { "dump-flows", "[-m] [--names] [dp] [filter=..] [type=..]", ++ 0, 5, dpctl_dump_flows, DP_RO }, + { "add-flow", "[dp] flow actions", 2, 3, dpctl_add_flow, DP_RW }, + { "mod-flow", "[dp] flow actions", 2, 3, dpctl_mod_flow, DP_RW }, + { "get-flow", "[dp] ufid", 1, 2, dpctl_get_flow, DP_RO }, + { "del-flow", "[dp] flow", 1, 2, dpctl_del_flow, DP_RW }, + { "del-flows", "[dp]", 0, 1, dpctl_del_flows, DP_RW }, +- { "dump-conntrack", "[dp] [zone=N]", 0, 2, dpctl_dump_conntrack, DP_RO }, ++ { "dump-conntrack", "[-m] [-s] [dp] [zone=N]", ++ 0, 4, dpctl_dump_conntrack, DP_RO }, + { "flush-conntrack", "[dp] [zone=N] [ct-tuple]", 0, 3, + dpctl_flush_conntrack, DP_RW }, + { "ct-stats-show", "[dp] [zone=N]", diff --git a/lib/dpif-netdev-private.h b/lib/dpif-netdev-private.h index 68c33a0f96..9b251f81fa 100644 --- a/lib/dpif-netdev-private.h @@ -39699,7 +39921,7 @@ index 68c33a0f96..9b251f81fa 100644 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c -index d393aab5e3..1d6b54ff16 100644 +index d393aab5e3..888325e5f2 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -83,9 +83,9 @@ @@ -39905,7 +40127,23 @@ index d393aab5e3..1d6b54ff16 100644 flow->dead = false; flow->batch = NULL; flow->mark = INVALID_FLOW_MARK; -@@ -3875,11 +3970,12 @@ dpif_netdev_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops, +@@ -3506,6 +3601,15 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put) + return error; + } + ++ if (match.wc.masks.in_port.odp_port != ODPP_NONE) { ++ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); ++ ++ VLOG_ERR_RL(&rl, "failed to put%s flow: in_port is not an exact match", ++ (put->flags & DPIF_FP_CREATE) ? "[create]" ++ : (put->flags & DPIF_FP_MODIFY) ? "[modify]" : "[zero]"); ++ return EINVAL; ++ } ++ + if (put->ufid) { + ufid = *put->ufid; + } else { +@@ -3875,11 +3979,12 @@ dpif_netdev_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops, /* Enable or Disable PMD auto load balancing. */ static void @@ -39919,7 +40157,7 @@ index d393aab5e3..1d6b54ff16 100644 bool enable_alb = false; bool multi_rxq = false; -@@ -3906,18 +4002,24 @@ set_pmd_auto_lb(struct dp_netdev *dp) +@@ -3906,18 +4011,24 @@ set_pmd_auto_lb(struct dp_netdev *dp) enable_alb = enable_alb && pmd_rxq_assign_cyc && pmd_alb->auto_lb_requested; @@ -39948,7 +40186,7 @@ index d393aab5e3..1d6b54ff16 100644 } /* Applies datapath configuration from the database. Some of the changes are -@@ -3935,6 +4037,9 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) +@@ -3935,6 +4046,9 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) uint32_t insert_min, cur_min; uint32_t tx_flush_interval, cur_tx_flush_interval; uint64_t rebalance_intvl; @@ -39958,7 +40196,7 @@ index d393aab5e3..1d6b54ff16 100644 tx_flush_interval = smap_get_int(other_config, "tx-flush-interval", DEFAULT_TX_FLUSH_INTERVAL); -@@ -4012,7 +4117,7 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) +@@ -4012,7 +4126,7 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) false); rebalance_intvl = smap_get_int(other_config, "pmd-auto-lb-rebal-interval", @@ -39967,7 +40205,7 @@ index d393aab5e3..1d6b54ff16 100644 /* Input is in min, convert it to msec. */ rebalance_intvl = -@@ -4020,9 +4125,38 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) +@@ -4020,9 +4134,38 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) if (pmd_alb->rebalance_intvl != rebalance_intvl) { pmd_alb->rebalance_intvl = rebalance_intvl; @@ -40009,7 +40247,7 @@ index d393aab5e3..1d6b54ff16 100644 return 0; } -@@ -4940,9 +5074,17 @@ reconfigure_datapath(struct dp_netdev *dp) +@@ -4940,9 +5083,17 @@ reconfigure_datapath(struct dp_netdev *dp) /* Check for all the ports that need reconfiguration. We cache this in * 'port->need_reconfigure', because netdev_is_reconf_required() can @@ -40029,7 +40267,7 @@ index d393aab5e3..1d6b54ff16 100644 port->need_reconfigure = true; } } -@@ -5076,7 +5218,7 @@ reconfigure_datapath(struct dp_netdev *dp) +@@ -5076,7 +5227,7 @@ reconfigure_datapath(struct dp_netdev *dp) reload_affected_pmds(dp); /* Check if PMD Auto LB is to be enabled */ @@ -40038,7 +40276,7 @@ index d393aab5e3..1d6b54ff16 100644 } /* Returns true if one of the netdevs in 'dp' requires a reconfiguration */ -@@ -5320,7 +5462,7 @@ pmd_rebalance_dry_run(struct dp_netdev *dp) +@@ -5320,7 +5471,7 @@ pmd_rebalance_dry_run(struct dp_netdev *dp) improvement = ((curr_variance - new_variance) * 100) / curr_variance; } @@ -40047,7 +40285,7 @@ index d393aab5e3..1d6b54ff16 100644 ret = false; } } -@@ -8040,6 +8182,7 @@ dp_netdev_pmd_try_optimize(struct dp_netdev_pmd_thread *pmd, +@@ -8040,6 +8191,7 @@ dp_netdev_pmd_try_optimize(struct dp_netdev_pmd_thread *pmd, if (pmd->ctx.now > pmd->rxq_next_cycle_store) { uint64_t curr_tsc; @@ -40055,7 +40293,7 @@ index d393aab5e3..1d6b54ff16 100644 struct pmd_auto_lb *pmd_alb = &pmd->dp->pmd_alb; if (pmd_alb->is_enabled && !pmd->isolated && (pmd->perf_stats.counters.n[PMD_CYCLES_ITER_IDLE] >= -@@ -8056,7 +8199,9 @@ dp_netdev_pmd_try_optimize(struct dp_netdev_pmd_thread *pmd, +@@ -8056,7 +8208,9 @@ dp_netdev_pmd_try_optimize(struct dp_netdev_pmd_thread *pmd, pmd_load = ((tot_proc * 100) / (tot_idle + tot_proc)); } @@ -40123,6 +40361,27 @@ index 45bb96b543..353d5cd3ed 100644 return false; } +diff --git a/lib/ipf.c b/lib/ipf.c +index 446e89d13c..c20bcc0b33 100644 +--- a/lib/ipf.c ++++ b/lib/ipf.c +@@ -1153,7 +1153,7 @@ ipf_post_execute_reass_pkts(struct ipf *ipf, + /* Inner batch loop is constant time since batch size is <= + * NETDEV_MAX_BURST. */ + DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) { +- if (pkt == rp->list->reass_execute_ctx) { ++ if (rp && pkt == rp->list->reass_execute_ctx) { + for (int i = 0; i <= rp->list->last_inuse_idx; i++) { + rp->list->frag_list[i].pkt->md.ct_label = pkt->md.ct_label; + rp->list->frag_list[i].pkt->md.ct_mark = pkt->md.ct_mark; +@@ -1206,6 +1206,7 @@ ipf_post_execute_reass_pkts(struct ipf *ipf, + ipf_reassembled_list_remove(rp); + dp_packet_delete(rp->pkt); + free(rp); ++ rp = NULL; + } else { + dp_packet_batch_refill(pb, pkt, pb_idx); + } diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c index ed748dbde7..e74771e2bc 100644 --- a/lib/jsonrpc.c @@ -40553,7 +40812,7 @@ index 90b405c737..309dc59c5f 100644 diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c -index 6187129c00..7051c31053 100644 +index 6187129c00..f080dec61f 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -152,9 +152,18 @@ typedef uint16_t dpdk_port_t; @@ -40641,7 +40900,51 @@ index 6187129c00..7051c31053 100644 } else { VLOG_WARN("%s: Tx TSO offload is not supported.", netdev_get_name(&dev->up)); -@@ -5110,7 +5134,11 @@ netdev_dpdk_reconfigure(struct netdev *netdev) +@@ -2691,12 +2715,8 @@ dpdk_pktmbuf_attach_extbuf(struct rte_mbuf *pkt, uint32_t data_len) + uint16_t buf_len; + void *buf; + +- if (rte_pktmbuf_tailroom(pkt) >= sizeof *shinfo) { +- shinfo = rte_pktmbuf_mtod(pkt, struct rte_mbuf_ext_shared_info *); +- } else { +- total_len += sizeof *shinfo + sizeof(uintptr_t); +- total_len = RTE_ALIGN_CEIL(total_len, sizeof(uintptr_t)); +- } ++ total_len += sizeof *shinfo + sizeof(uintptr_t); ++ total_len = RTE_ALIGN_CEIL(total_len, sizeof(uintptr_t)); + + if (OVS_UNLIKELY(total_len > UINT16_MAX)) { + VLOG_ERR("Can't copy packet: too big %u", total_len); +@@ -2711,20 +2731,14 @@ dpdk_pktmbuf_attach_extbuf(struct rte_mbuf *pkt, uint32_t data_len) + } + + /* Initialize shinfo. */ +- if (shinfo) { +- shinfo->free_cb = netdev_dpdk_extbuf_free; +- shinfo->fcb_opaque = buf; +- rte_mbuf_ext_refcnt_set(shinfo, 1); +- } else { +- shinfo = rte_pktmbuf_ext_shinfo_init_helper(buf, &buf_len, +- netdev_dpdk_extbuf_free, +- buf); +- if (OVS_UNLIKELY(shinfo == NULL)) { +- rte_free(buf); +- VLOG_ERR("Failed to initialize shared info for mbuf while " +- "attempting to attach an external buffer."); +- return NULL; +- } ++ shinfo = rte_pktmbuf_ext_shinfo_init_helper(buf, &buf_len, ++ netdev_dpdk_extbuf_free, ++ buf); ++ if (OVS_UNLIKELY(shinfo == NULL)) { ++ rte_free(buf); ++ VLOG_ERR("Failed to initialize shared info for mbuf while " ++ "attempting to attach an external buffer."); ++ return NULL; + } + + rte_pktmbuf_attach_extbuf(pkt, buf, rte_malloc_virt2iova(buf), buf_len, +@@ -5110,7 +5124,11 @@ netdev_dpdk_reconfigure(struct netdev *netdev) if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_TSO; netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM; @@ -40653,7 +40956,7 @@ index 6187129c00..7051c31053 100644 } dev->tx_q = netdev_dpdk_alloc_txq(netdev->n_txq); -@@ -5186,6 +5214,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) +@@ -5186,6 +5204,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); int err; uint64_t vhost_flags = 0; @@ -40661,7 +40964,7 @@ index 6187129c00..7051c31053 100644 bool zc_enabled; ovs_mutex_lock(&dev->mutex); -@@ -5251,17 +5280,24 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) +@@ -5251,17 +5270,24 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) if (userspace_tso_enabled()) { netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_TSO; netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM; @@ -40696,7 +40999,7 @@ index 6187129c00..7051c31053 100644 err = rte_vhost_driver_start(dev->vhost_id); diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c -index c6f3d27409..8d779945a1 100644 +index c6f3d27409..177261f96b 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -231,6 +231,14 @@ struct rtnl_link_stats64 { @@ -40748,6 +41051,42 @@ index c6f3d27409..8d779945a1 100644 netdev_->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM; } +@@ -1233,21 +1242,21 @@ netdev_linux_batch_rxq_recv_sock(struct netdev_rxq_linux *rx, int mtu, + * aux_buf is allocated so that it can be prepended to TSO buffer. */ + std_len = virtio_net_hdr_size + VLAN_ETH_HEADER_LEN + mtu; + for (i = 0; i < NETDEV_MAX_BURST; i++) { +- buffers[i] = dp_packet_new_with_headroom(std_len, DP_NETDEV_HEADROOM); +- iovs[i][IOV_PACKET].iov_base = dp_packet_data(buffers[i]); +- iovs[i][IOV_PACKET].iov_len = std_len; +- if (iovlen == IOV_TSO_SIZE) { +- iovs[i][IOV_AUXBUF].iov_base = dp_packet_data(rx->aux_bufs[i]); +- iovs[i][IOV_AUXBUF].iov_len = dp_packet_tailroom(rx->aux_bufs[i]); +- } ++ buffers[i] = dp_packet_new_with_headroom(std_len, DP_NETDEV_HEADROOM); ++ iovs[i][IOV_PACKET].iov_base = dp_packet_data(buffers[i]); ++ iovs[i][IOV_PACKET].iov_len = std_len; ++ if (iovlen == IOV_TSO_SIZE) { ++ iovs[i][IOV_AUXBUF].iov_base = dp_packet_data(rx->aux_bufs[i]); ++ iovs[i][IOV_AUXBUF].iov_len = dp_packet_tailroom(rx->aux_bufs[i]); ++ } + +- mmsgs[i].msg_hdr.msg_name = NULL; +- mmsgs[i].msg_hdr.msg_namelen = 0; +- mmsgs[i].msg_hdr.msg_iov = iovs[i]; +- mmsgs[i].msg_hdr.msg_iovlen = iovlen; +- mmsgs[i].msg_hdr.msg_control = &cmsg_buffers[i]; +- mmsgs[i].msg_hdr.msg_controllen = sizeof cmsg_buffers[i]; +- mmsgs[i].msg_hdr.msg_flags = 0; ++ mmsgs[i].msg_hdr.msg_name = NULL; ++ mmsgs[i].msg_hdr.msg_namelen = 0; ++ mmsgs[i].msg_hdr.msg_iov = iovs[i]; ++ mmsgs[i].msg_hdr.msg_iovlen = iovlen; ++ mmsgs[i].msg_hdr.msg_control = &cmsg_buffers[i]; ++ mmsgs[i].msg_hdr.msg_controllen = sizeof cmsg_buffers[i]; ++ mmsgs[i].msg_hdr.msg_flags = 0; + } + + do { diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index f8c46bbaad..b42d314b65 100644 --- a/lib/netdev-offload-dpdk.c @@ -40892,7 +41231,7 @@ index f8c46bbaad..b42d314b65 100644 static int diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c -index 550e440b3a..a1d7ffad70 100644 +index 550e440b3a..c00505d181 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -198,7 +198,9 @@ del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid) @@ -40906,7 +41245,39 @@ index 550e440b3a..a1d7ffad70 100644 return err; } -@@ -1727,7 +1729,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1578,6 +1580,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, + flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; + } + flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW; ++ mask->ct_state &= ~OVS_CS_F_NEW; + } + + if (mask->ct_state & OVS_CS_F_ESTABLISHED) { +@@ -1585,6 +1588,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, + flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; + } + flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED; ++ mask->ct_state &= ~OVS_CS_F_ESTABLISHED; + } + + if (mask->ct_state & OVS_CS_F_TRACKED) { +@@ -1592,14 +1596,13 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, + flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; + } + flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED; ++ mask->ct_state &= ~OVS_CS_F_TRACKED; + } + + if (flower.key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED) { + flower.key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); + flower.mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); + } +- +- mask->ct_state = 0; + } + + if (mask->ct_zone) { +@@ -1727,7 +1730,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, if (get_ufid_tc_mapping(ufid, &id) == 0) { VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d", id.handle, id.prio); @@ -40915,7 +41286,7 @@ index 550e440b3a..a1d7ffad70 100644 } prio = get_prio_for_tc_flower(&flower); -@@ -1907,6 +1909,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -1907,6 +1910,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) static struct ovsthread_once block_once = OVSTHREAD_ONCE_INITIALIZER; enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev); uint32_t block_id = 0; @@ -40923,7 +41294,7 @@ index 550e440b3a..a1d7ffad70 100644 int ifindex; int error; -@@ -1917,11 +1920,21 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -1917,11 +1921,21 @@ netdev_tc_init_flow_api(struct netdev *netdev) return -ifindex; } @@ -40945,7 +41316,7 @@ index 550e440b3a..a1d7ffad70 100644 ovsthread_once_done(&block_once); } -@@ -1930,7 +1943,6 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -1930,7 +1944,6 @@ netdev_tc_init_flow_api(struct netdev *netdev) ovsthread_once_done(&multi_mask_once); } @@ -41097,10 +41468,20 @@ index 42d3335f0f..97320a4dba 100644 } else { a = attrs[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL]; diff --git a/lib/odp-util.c b/lib/odp-util.c -index 746d1e97d4..41cbac0c97 100644 +index 746d1e97d4..b288269fc4 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c -@@ -1441,14 +1441,20 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions) +@@ -390,7 +390,8 @@ format_odp_push_nsh_action(struct ds *ds, + break; + } + default: +- OVS_NOT_REACHED(); ++ ds_put_cstr(ds, ","); ++ break; + } + ds_put_format(ds, ")"); + } +@@ -1441,14 +1442,20 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions) int n1 = -1; if (ovs_scan(&s[n], ",tunnel_out_port=%"SCNi32")%n", &tunnel_out_port, &n1)) { @@ -41127,7 +41508,7 @@ index 746d1e97d4..41cbac0c97 100644 goto out; } } -@@ -5428,13 +5434,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) +@@ -5428,13 +5435,16 @@ erspan_to_attr(struct ofpbuf *a, const void *data_) do { \ len = 0; @@ -41151,7 +41532,7 @@ index 746d1e97d4..41cbac0c97 100644 } #define SCAN_FIELD_NESTED__(NAME, TYPE, SCAN_AS, ATTR, FUNC) \ -@@ -6225,7 +6234,9 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, +@@ -6225,7 +6235,9 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, struct ovs_key_nd_extensions *nd_ext_key; if (data->igmp_group_ip4 != 0 || data->tcp_flags != 0) { @@ -41162,7 +41543,7 @@ index 746d1e97d4..41cbac0c97 100644 OVS_KEY_ATTR_ND_EXTENSIONS, sizeof *nd_ext_key); nd_ext_key->nd_reserved = data->igmp_group_ip4; -@@ -6275,6 +6286,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) +@@ -6275,6 +6287,10 @@ odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet) nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, md->skb_priority); @@ -41173,7 +41554,7 @@ index 746d1e97d4..41cbac0c97 100644 if (flow_tnl_dst_is_set(&md->tunnel)) { tun_key_to_attr(buf, &md->tunnel, &md->tunnel, NULL, NULL); } -@@ -7416,15 +7431,18 @@ odp_key_fitness_to_string(enum odp_key_fitness fitness) +@@ -7416,15 +7432,18 @@ odp_key_fitness_to_string(enum odp_key_fitness fitness) /* Appends an OVS_ACTION_ATTR_USERSPACE action to 'odp_actions' that specifies * Netlink PID 'pid'. If 'userdata' is nonnull, adds a userdata attribute @@ -41197,7 +41578,7 @@ index 746d1e97d4..41cbac0c97 100644 { size_t userdata_ofs; size_t offset; -@@ -7432,6 +7450,9 @@ odp_put_userspace_action(uint32_t pid, +@@ -7432,6 +7451,9 @@ odp_put_userspace_action(uint32_t pid, offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_USERSPACE); nl_msg_put_u32(odp_actions, OVS_USERSPACE_ATTR_PID, pid); if (userdata) { @@ -41207,7 +41588,7 @@ index 746d1e97d4..41cbac0c97 100644 userdata_ofs = odp_actions->size + NLA_HDRLEN; /* The OVS kernel module before OVS 1.11 and the upstream Linux kernel -@@ -7457,9 +7478,16 @@ odp_put_userspace_action(uint32_t pid, +@@ -7457,9 +7479,16 @@ odp_put_userspace_action(uint32_t pid, if (include_actions) { nl_msg_put_flag(odp_actions, OVS_USERSPACE_ATTR_ACTIONS); } @@ -41225,7 +41606,7 @@ index 746d1e97d4..41cbac0c97 100644 } void -@@ -7565,6 +7593,28 @@ struct offsetof_sizeof { +@@ -7565,6 +7594,28 @@ struct offsetof_sizeof { int size; }; @@ -41254,7 +41635,7 @@ index 746d1e97d4..41cbac0c97 100644 /* Compares each of the fields in 'key0' and 'key1'. The fields are specified * in 'offsetof_sizeof_arr', which is an array terminated by a 0-size field. * Returns true if all of the fields are equal, false if at least one differs. -@@ -7643,9 +7693,10 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, +@@ -7643,9 +7694,10 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, struct flow_wildcards *wc, bool use_masked) { @@ -41266,7 +41647,7 @@ index 746d1e97d4..41cbac0c97 100644 if (flow->packet_type != htonl(PT_ETH)) { return; } -@@ -7653,11 +7704,13 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, +@@ -7653,11 +7705,13 @@ commit_set_ether_action(const struct flow *flow, struct flow *base_flow, get_ethernet_key(flow, &key); get_ethernet_key(base_flow, &base); get_ethernet_key(&wc->masks, &mask); @@ -41280,7 +41661,7 @@ index 746d1e97d4..41cbac0c97 100644 put_ethernet_key(&mask, &wc->masks); } } -@@ -7781,7 +7834,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, +@@ -7781,7 +7835,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -41289,7 +41670,7 @@ index 746d1e97d4..41cbac0c97 100644 struct offsetof_sizeof ovs_key_ipv4_offsetof_sizeof_arr[] = OVS_KEY_IPV4_OFFSETOF_SIZEOF_ARR; -@@ -7792,6 +7845,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, +@@ -7792,6 +7846,7 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, get_ipv4_key(flow, &key, false); get_ipv4_key(base_flow, &base, false); get_ipv4_key(&wc->masks, &mask, true); @@ -41297,7 +41678,7 @@ index 746d1e97d4..41cbac0c97 100644 mask.ipv4_proto = 0; /* Not writeable. */ mask.ipv4_frag = 0; /* Not writable. */ -@@ -7803,9 +7857,8 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, +@@ -7803,9 +7858,8 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, if (commit(OVS_KEY_ATTR_IPV4, use_masked, &key, &base, &mask, sizeof key, ovs_key_ipv4_offsetof_sizeof_arr, odp_actions)) { put_ipv4_key(&base, base_flow, false); @@ -41309,7 +41690,7 @@ index 746d1e97d4..41cbac0c97 100644 } } -@@ -7838,7 +7891,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, +@@ -7838,7 +7892,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -41318,7 +41699,7 @@ index 746d1e97d4..41cbac0c97 100644 struct offsetof_sizeof ovs_key_ipv6_offsetof_sizeof_arr[] = OVS_KEY_IPV6_OFFSETOF_SIZEOF_ARR; -@@ -7849,6 +7902,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, +@@ -7849,6 +7903,7 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, get_ipv6_key(flow, &key, false); get_ipv6_key(base_flow, &base, false); get_ipv6_key(&wc->masks, &mask, true); @@ -41326,7 +41707,7 @@ index 746d1e97d4..41cbac0c97 100644 mask.ipv6_proto = 0; /* Not writeable. */ mask.ipv6_frag = 0; /* Not writable. */ mask.ipv6_label &= htonl(IPV6_LABEL_MASK); /* Not writable. */ -@@ -7861,9 +7915,8 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, +@@ -7861,9 +7916,8 @@ commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow, if (commit(OVS_KEY_ATTR_IPV6, use_masked, &key, &base, &mask, sizeof key, ovs_key_ipv6_offsetof_sizeof_arr, odp_actions)) { put_ipv6_key(&base, base_flow, false); @@ -41338,7 +41719,7 @@ index 746d1e97d4..41cbac0c97 100644 } } -@@ -7894,17 +7947,19 @@ static enum slow_path_reason +@@ -7894,17 +7948,19 @@ static enum slow_path_reason commit_set_arp_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc) { @@ -41359,7 +41740,7 @@ index 746d1e97d4..41cbac0c97 100644 put_arp_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -7931,7 +7986,7 @@ static enum slow_path_reason +@@ -7931,7 +7987,7 @@ static enum slow_path_reason commit_set_icmp_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc) { @@ -41368,7 +41749,7 @@ index 746d1e97d4..41cbac0c97 100644 struct offsetof_sizeof ovs_key_icmp_offsetof_sizeof_arr[] = OVS_KEY_ICMP_OFFSETOF_SIZEOF_ARR; enum ovs_key_attr attr; -@@ -7947,10 +8002,12 @@ commit_set_icmp_action(const struct flow *flow, struct flow *base_flow, +@@ -7947,10 +8003,12 @@ commit_set_icmp_action(const struct flow *flow, struct flow *base_flow, get_icmp_key(flow, &key); get_icmp_key(base_flow, &base); get_icmp_key(&wc->masks, &mask); @@ -41381,7 +41762,7 @@ index 746d1e97d4..41cbac0c97 100644 put_icmp_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -7998,17 +8055,19 @@ commit_set_nd_action(const struct flow *flow, struct flow *base_flow, +@@ -7998,17 +8056,19 @@ commit_set_nd_action(const struct flow *flow, struct flow *base_flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -41402,7 +41783,7 @@ index 746d1e97d4..41cbac0c97 100644 put_nd_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -8022,18 +8081,20 @@ commit_set_nd_extensions_action(const struct flow *flow, +@@ -8022,18 +8082,20 @@ commit_set_nd_extensions_action(const struct flow *flow, struct ofpbuf *odp_actions, struct flow_wildcards *wc, bool use_masked) { @@ -41424,7 +41805,7 @@ index 746d1e97d4..41cbac0c97 100644 put_nd_extensions_key(&mask, &wc->masks); return SLOW_ACTION; } -@@ -8248,7 +8309,7 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, +@@ -8248,7 +8310,7 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, bool use_masked) { enum ovs_key_attr key_type; @@ -41433,7 +41814,7 @@ index 746d1e97d4..41cbac0c97 100644 struct offsetof_sizeof ovs_key_tp_offsetof_sizeof_arr[] = OVS_KEY_TCP_OFFSETOF_SIZEOF_ARR; -@@ -8274,10 +8335,12 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, +@@ -8274,10 +8336,12 @@ commit_set_port_action(const struct flow *flow, struct flow *base_flow, get_tp_key(flow, &key); get_tp_key(base_flow, &base); get_tp_key(&wc->masks, &mask); @@ -41446,7 +41827,7 @@ index 746d1e97d4..41cbac0c97 100644 put_tp_key(&mask, &wc->masks); } } -@@ -8301,7 +8364,7 @@ commit_set_priority_action(const struct flow *flow, struct flow *base_flow, +@@ -8301,7 +8365,7 @@ commit_set_priority_action(const struct flow *flow, struct flow *base_flow, if (commit(OVS_KEY_ATTR_PRIORITY, use_masked, &key, &base, &mask, sizeof key, ovs_key_prio_offsetof_sizeof_arr, odp_actions)) { base_flow->skb_priority = base; @@ -41455,7 +41836,7 @@ index 746d1e97d4..41cbac0c97 100644 } } -@@ -8325,7 +8388,7 @@ commit_set_pkt_mark_action(const struct flow *flow, struct flow *base_flow, +@@ -8325,7 +8389,7 @@ commit_set_pkt_mark_action(const struct flow *flow, struct flow *base_flow, sizeof key, ovs_key_pkt_mark_offsetof_sizeof_arr, odp_actions)) { base_flow->pkt_mark = base; @@ -41487,10 +41868,26 @@ index 4ecce1aac5..936fadf175 100644 struct ofpbuf *odp_actions, const char *tnl_type); diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c -index ddef3b0c87..ef8b2b4527 100644 +index ddef3b0c87..6a6fdb3e5f 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c -@@ -6657,6 +6657,7 @@ parse_CT(char *arg, const struct ofpact_parse_params *pp) +@@ -4346,6 +4346,7 @@ decode_NXAST_RAW_ENCAP(const struct nx_action_encap *nae, + { + struct ofpact_encap *encap; + const struct ofp_ed_prop_header *ofp_prop; ++ const size_t encap_ofs = out->size; + size_t props_len; + uint16_t n_props = 0; + int err; +@@ -4373,6 +4374,7 @@ decode_NXAST_RAW_ENCAP(const struct nx_action_encap *nae, + } + n_props++; + } ++ encap = ofpbuf_at_assert(out, encap_ofs, sizeof *encap); + encap->n_props = n_props; + out->header = &encap->ofpact; + ofpact_finish_ENCAP(out, &encap); +@@ -6657,6 +6659,7 @@ parse_CT(char *arg, const struct ofpact_parse_params *pp) } if (ofpbuf_oversized(pp->ofpacts)) { @@ -42297,9 +42694,18 @@ index eda265dfc5..a635ff7689 100644 #define SHA1_FMT \ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \ diff --git a/lib/tc.c b/lib/tc.c -index 12af0192b6..e772aa515c 100644 +index 12af0192b6..5a6f76a209 100644 --- a/lib/tc.c +++ b/lib/tc.c +@@ -456,7 +456,7 @@ nl_parse_flower_mpls(struct nlattr **attrs, struct tc_flower *flower) + if (attrs[TCA_FLOWER_KEY_MPLS_BOS]) { + bos = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_MPLS_BOS]); + set_mpls_lse_bos(&flower->key.mpls_lse, bos); +- set_mpls_lse_ttl(&flower->mask.mpls_lse, 0xff); ++ set_mpls_lse_bos(&flower->mask.mpls_lse, 0xff); + } + + if (attrs[TCA_FLOWER_KEY_MPLS_TC]) { @@ -934,6 +934,7 @@ nl_parse_act_pedit(struct nlattr *options, struct tc_flower *flower) int flower_off = m->flower_offset; int sz = m->size; @@ -42384,7 +42790,7 @@ index 7ad8758fe6..067dcad157 100644 void *dst, unsigned int dst_len, unsigned int dst_ofs, unsigned int n_bits); diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c -index 51d656cba9..aee676d93e 100644 +index 51d656cba9..fd926cbb82 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -190,8 +190,8 @@ struct ofservice { @@ -42445,6 +42851,26 @@ index 51d656cba9..aee676d93e 100644 } /* Finds and returns the ofservice within 'mgr' that has the given +@@ -2131,7 +2140,7 @@ ofmonitor_report(struct connmgr *mgr, struct rule *rule, + const struct rule_actions *old_actions) + OVS_REQUIRES(ofproto_mutex) + { +- if (rule_is_hidden(rule)) { ++ if (!mgr || rule_is_hidden(rule)) { + return; + } + +@@ -2235,6 +2244,10 @@ ofmonitor_flush(struct connmgr *mgr) + { + struct ofconn *ofconn; + ++ if (!mgr) { ++ return; ++ } ++ + LIST_FOR_EACH (ofconn, connmgr_node, &mgr->conns) { + struct rconn_packet_counter *counter = ofconn->monitor_counter; + diff --git a/ofproto/ipfix-gen-entities b/ofproto/ipfix-gen-entities index 0be719967d..d5abe9c2ed 100755 --- a/ofproto/ipfix-gen-entities @@ -42638,10 +43064,10 @@ index 08830d8371..8594afad4a 100644 ovs_mutex_unlock(&ofproto_mutex); } diff --git a/ovsdb/automake.mk b/ovsdb/automake.mk -index b895f42925..d60f3f4ec8 100644 +index b895f42925..446d6c1362 100644 --- a/ovsdb/automake.mk +++ b/ovsdb/automake.mk -@@ -106,7 +106,7 @@ CLEANFILES += $(OVSIDL_BUILT) +@@ -106,11 +106,12 @@ CLEANFILES += $(OVSIDL_BUILT) # However, current versions of Automake seem to output all variable # assignments before any targets, so it doesn't seem to be a problem, # at least for now. @@ -42650,6 +43076,11 @@ index b895f42925..d60f3f4ec8 100644 # ovsdb-doc EXTRA_DIST += ovsdb/ovsdb-doc + OVSDB_DOC = $(run_python) $(srcdir)/ovsdb/ovsdb-doc ++ovsdb/ovsdb-doc: python/ovs/dirs.py + + # ovsdb-dot + EXTRA_DIST += ovsdb/ovsdb-dot.in ovsdb/dot2pic diff --git a/ovsdb/dot2pic b/ovsdb/dot2pic index de67261ac6..2f858e19d5 100755 --- a/ovsdb/dot2pic @@ -42698,6 +43129,28 @@ index c82a79c9ff..f35faadfe0 100644 } if (fd < 0) { const char *op = (open_mode == OVSDB_LOG_CREATE_EXCL ? "create" +diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c +index 72756eb1f2..ba28e36d78 100644 +--- a/ovsdb/ovsdb-client.c ++++ b/ovsdb/ovsdb-client.c +@@ -1664,14 +1664,15 @@ static void + do_needs_conversion(struct jsonrpc *rpc, const char *database_ OVS_UNUSED, + int argc OVS_UNUSED, char *argv[]) + { ++ const char *schema_file_name = argv[argc - 1]; + struct ovsdb_schema *schema1; +- check_ovsdb_error(ovsdb_schema_from_file(argv[0], &schema1)); ++ check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema1)); + + char *database = schema1->name; + open_rpc(1, NEED_DATABASE, argc, argv, &rpc, &database); + + if (is_database_clustered(rpc, database)) { +- ovsdb_schema_persist_ephemeral_columns(schema1, argv[0]); ++ ovsdb_schema_persist_ephemeral_columns(schema1, schema_file_name); + } + + struct ovsdb_schema *schema2 = fetch_schema(rpc, schema1->name); diff --git a/ovsdb/ovsdb-doc b/ovsdb/ovsdb-doc index 406c293114..10d0c0c134 100755 --- a/ovsdb/ovsdb-doc @@ -43044,7 +43497,7 @@ index 18c83fe9c2..dd14d81091 100644 struct hmap servers; struct ovsdb_error *error = diff --git a/ovsdb/raft.c b/ovsdb/raft.c -index 4789bc4f22..ff06add0bf 100644 +index 4789bc4f22..d08a7bcb62 100644 --- a/ovsdb/raft.c +++ b/ovsdb/raft.c @@ -36,6 +36,7 @@ @@ -43093,17 +43546,52 @@ index 4789bc4f22..ff06add0bf 100644 return raft; } -@@ -932,6 +948,9 @@ raft_add_conn(struct raft *raft, struct jsonrpc_session *js, +@@ -918,6 +934,34 @@ raft_reset_ping_timer(struct raft *raft) + raft->ping_timeout = time_msec() + raft->election_timer / 3; + } + ++static void ++raft_conn_update_probe_interval(struct raft *raft, struct raft_conn *r_conn) ++{ ++ /* Inactivity probe will be sent if connection will remain idle for the ++ * time of an election timeout. Connection will be dropped if inactivity ++ * will last twice that time. ++ * ++ * It's not enough to just have heartbeats if connection is still ++ * established, but no packets received from the other side. Without ++ * inactivity probe follower will just try to initiate election ++ * indefinitely staying in 'candidate' role. And the leader will continue ++ * to send heartbeats to the dead connection thinking that remote server ++ * is still part of the cluster. */ ++ int probe_interval = raft->election_timer + ELECTION_RANGE_MSEC; ++ ++ jsonrpc_session_set_probe_interval(r_conn->js, probe_interval); ++} ++ ++static void ++raft_update_probe_intervals(struct raft *raft) ++{ ++ struct raft_conn *r_conn; ++ ++ LIST_FOR_EACH (r_conn, list_node, &raft->conns) { ++ raft_conn_update_probe_interval(raft, r_conn); ++ } ++} ++ + static void + raft_add_conn(struct raft *raft, struct jsonrpc_session *js, + const struct uuid *sid, bool incoming) +@@ -932,6 +976,9 @@ raft_add_conn(struct raft *raft, struct jsonrpc_session *js, &conn->sid); conn->incoming = incoming; conn->js_seqno = jsonrpc_session_get_seqno(conn->js); -+ jsonrpc_session_set_probe_interval(js, 0); ++ raft_conn_update_probe_interval(raft, conn); + jsonrpc_session_set_backlog_threshold(js, raft->conn_backlog_max_n_msgs, + raft->conn_backlog_max_n_bytes); } /* Starts the local server in an existing Raft cluster, using the local copy of -@@ -1007,6 +1026,23 @@ raft_get_sid(const struct raft *raft) +@@ -1007,6 +1054,23 @@ raft_get_sid(const struct raft *raft) return &raft->sid; } @@ -43127,7 +43615,7 @@ index 4789bc4f22..ff06add0bf 100644 /* Returns true if 'raft' has completed joining its cluster, has not left or * initiated leaving the cluster, does not have failed disk storage, and is * apparently connected to the leader in a healthy way (or is itself the -@@ -1020,12 +1056,22 @@ raft_get_sid(const struct raft *raft) +@@ -1020,12 +1084,22 @@ raft_get_sid(const struct raft *raft) bool raft_is_connected(const struct raft *raft) { @@ -43152,7 +43640,7 @@ index 4789bc4f22..ff06add0bf 100644 return ret; } -@@ -1397,8 +1443,19 @@ raft_conn_run(struct raft *raft, struct raft_conn *conn) +@@ -1397,8 +1471,19 @@ raft_conn_run(struct raft *raft, struct raft_conn *conn) jsonrpc_session_run(conn->js); unsigned int new_seqno = jsonrpc_session_get_seqno(conn->js); @@ -43173,7 +43661,7 @@ index 4789bc4f22..ff06add0bf 100644 conn->js_seqno = new_seqno; if (just_connected) { if (raft->joining) { -@@ -1641,6 +1698,7 @@ raft_start_election(struct raft *raft, bool leadership_transfer) +@@ -1641,6 +1726,7 @@ raft_start_election(struct raft *raft, bool leadership_transfer) } ovs_assert(raft->role != RAFT_LEADER); @@ -43181,7 +43669,7 @@ index 4789bc4f22..ff06add0bf 100644 raft->role = RAFT_CANDIDATE; /* If there was no leader elected since last election, we know we are * retrying now. */ -@@ -1684,7 +1742,9 @@ raft_start_election(struct raft *raft, bool leadership_transfer) +@@ -1684,7 +1770,9 @@ raft_start_election(struct raft *raft, bool leadership_transfer) .leadership_transfer = leadership_transfer, }, }; @@ -43192,7 +43680,7 @@ index 4789bc4f22..ff06add0bf 100644 } /* Vote for ourselves. */ -@@ -2513,13 +2573,14 @@ raft_server_init_leader(struct raft *raft, struct raft_server *s) +@@ -2513,13 +2601,14 @@ raft_server_init_leader(struct raft *raft, struct raft_server *s) s->match_index = 0; s->phase = RAFT_PHASE_STABLE; s->replied = false; @@ -43208,7 +43696,23 @@ index 4789bc4f22..ff06add0bf 100644 raft->candidate_retrying = false; } -@@ -2960,6 +3021,15 @@ raft_update_leader(struct raft *raft, const struct uuid *sid) +@@ -2731,6 +2820,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) + raft->election_timer, e->election_timer); + raft->election_timer = e->election_timer; + raft->election_timer_new = 0; ++ raft_update_probe_intervals(raft); + } + if (e->servers) { + /* raft_run_reconfigure() can write a new Raft entry, which can +@@ -2747,6 +2837,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) + VLOG_INFO("Election timer changed from %"PRIu64" to %"PRIu64, + raft->election_timer, e->election_timer); + raft->election_timer = e->election_timer; ++ raft_update_probe_intervals(raft); + } + } + /* Check if any pending command can be completed, and complete it. +@@ -2960,6 +3051,15 @@ raft_update_leader(struct raft *raft, const struct uuid *sid) }; ignore(ovsdb_log_write_and_free(raft->log, raft_record_to_json(&r))); } @@ -43224,7 +43728,7 @@ index 4789bc4f22..ff06add0bf 100644 return true; } -@@ -3260,7 +3330,20 @@ raft_send_install_snapshot_request(struct raft *raft, +@@ -3260,7 +3360,20 @@ raft_send_install_snapshot_request(struct raft *raft, .election_timer = raft->election_timer, /* use latest value */ } }; @@ -43246,7 +43750,7 @@ index 4789bc4f22..ff06add0bf 100644 } static void -@@ -3913,7 +3996,7 @@ raft_handle_install_snapshot_request__( +@@ -3913,7 +4026,7 @@ raft_handle_install_snapshot_request__( struct ovsdb_error *error = raft_save_snapshot(raft, new_log_start, &new_snapshot); if (error) { @@ -43255,7 +43759,7 @@ index 4789bc4f22..ff06add0bf 100644 VLOG_WARN("could not save snapshot: %s", error_s); free(error_s); return false; -@@ -3977,6 +4060,8 @@ raft_handle_install_snapshot_reply( +@@ -3977,6 +4090,8 @@ raft_handle_install_snapshot_reply( } } @@ -43264,7 +43768,7 @@ index 4789bc4f22..ff06add0bf 100644 if (rpy->last_index != raft->log_start - 1 || rpy->last_term != raft->snap.term) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); -@@ -3992,8 +4077,9 @@ raft_handle_install_snapshot_reply( +@@ -3992,8 +4107,9 @@ raft_handle_install_snapshot_reply( VLOG_INFO_RL(&rl, "cluster "CID_FMT": installed snapshot on server %s " " up to %"PRIu64":%"PRIu64, CID_ARGS(&raft->cid), s->nickname, rpy->last_term, rpy->last_index); @@ -43276,7 +43780,7 @@ index 4789bc4f22..ff06add0bf 100644 } /* Returns true if 'raft' has grown enough since the last snapshot that -@@ -4143,9 +4229,7 @@ raft_handle_execute_command_request__( +@@ -4143,9 +4259,7 @@ raft_handle_execute_command_request__( cmd->sid = rq->common.sid; enum raft_command_status status = cmd->status; @@ -43287,7 +43791,16 @@ index 4789bc4f22..ff06add0bf 100644 return status; } -@@ -4639,6 +4723,42 @@ raft_unixctl_change_election_timer(struct unixctl_conn *conn, +@@ -4366,6 +4480,8 @@ raft_unixctl_status(struct unixctl_conn *conn, + : raft->leaving ? "leaving cluster" + : raft->left ? "left cluster" + : raft->failed ? "failed" ++ : raft->candidate_retrying ++ ? "disconnected from the cluster (election timeout)" + : "cluster member"); + if (raft->joining) { + ds_put_format(&s, "Remotes for joining:"); +@@ -4639,6 +4755,42 @@ raft_unixctl_change_election_timer(struct unixctl_conn *conn, unixctl_command_reply(conn, "change of election timer initiated."); } @@ -43330,7 +43843,7 @@ index 4789bc4f22..ff06add0bf 100644 static void raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, int argc OVS_UNUSED, const char *argv[], -@@ -4667,6 +4787,8 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, +@@ -4667,6 +4819,8 @@ raft_unixctl_failure_test(struct unixctl_conn *conn OVS_UNUSED, raft_reset_election_timer(raft); } } @@ -43339,7 +43852,7 @@ index 4789bc4f22..ff06add0bf 100644 } else if (!strcmp(test, "clear")) { failure_test = FT_NO_TEST; unixctl_command_reply(conn, "test dismissed"); -@@ -4697,6 +4819,9 @@ raft_init(void) +@@ -4697,6 +4851,9 @@ raft_init(void) raft_unixctl_kick, NULL); unixctl_command_register("cluster/change-election-timer", "DB TIME", 2, 2, raft_unixctl_change_election_timer, NULL); @@ -43534,10 +44047,128 @@ index 9852786466..8bbcd824f4 100644 version.py +dirs.py diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py -index 020291d486..5850ac7abf 100644 +index 020291d486..4226d1cb2f 100644 --- a/python/ovs/db/idl.py +++ b/python/ovs/db/idl.py -@@ -1567,10 +1567,9 @@ class Transaction(object): +@@ -12,6 +12,7 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + ++import collections + import functools + import uuid + +@@ -39,6 +40,10 @@ OVSDB_UPDATE2 = 1 + CLUSTERED = "clustered" + + ++Notice = collections.namedtuple('Notice', ('event', 'row', 'updates')) ++Notice.__new__.__defaults__ = (None,) # default updates=None ++ ++ + class Idl(object): + """Open vSwitch Database Interface Definition Language (OVSDB IDL). + +@@ -614,6 +619,7 @@ class Idl(object): + raise error.Error(" is not an object", + table_updates) + ++ notices = [] + for table_name, table_update in table_updates.items(): + table = tables.get(table_name) + if not table: +@@ -639,7 +645,9 @@ class Idl(object): + % (table_name, uuid_string)) + + if version == OVSDB_UPDATE2: +- if self.__process_update2(table, uuid, row_update): ++ changes = self.__process_update2(table, uuid, row_update) ++ if changes: ++ notices.append(changes) + self.change_seqno += 1 + continue + +@@ -652,17 +660,20 @@ class Idl(object): + raise error.Error(' missing "old" and ' + '"new" members', row_update) + +- if self.__process_update(table, uuid, old, new): ++ changes = self.__process_update(table, uuid, old, new) ++ if changes: ++ notices.append(changes) + self.change_seqno += 1 ++ for notice in notices: ++ self.notify(*notice) + + def __process_update2(self, table, uuid, row_update): ++ """Returns Notice if a column changed, False otherwise.""" + row = table.rows.get(uuid) +- changed = False + if "delete" in row_update: + if row: + del table.rows[uuid] +- self.notify(ROW_DELETE, row) +- changed = True ++ return Notice(ROW_DELETE, row) + else: + # XXX rate-limit + vlog.warn("cannot delete missing row %s from table" +@@ -681,29 +692,27 @@ class Idl(object): + changed = self.__row_update(table, row, row_update) + table.rows[uuid] = row + if changed: +- self.notify(ROW_CREATE, row) ++ return Notice(ROW_CREATE, row) + elif "modify" in row_update: + if not row: + raise error.Error('Modify non-existing row') + + old_row = self.__apply_diff(table, row, row_update['modify']) +- self.notify(ROW_UPDATE, row, Row(self, table, uuid, old_row)) +- changed = True ++ return Notice(ROW_UPDATE, row, Row(self, table, uuid, old_row)) + else: + raise error.Error(' unknown operation', + row_update) +- return changed ++ return False + + def __process_update(self, table, uuid, old, new): +- """Returns True if a column changed, False otherwise.""" ++ """Returns Notice if a column changed, False otherwise.""" + row = table.rows.get(uuid) + changed = False + if not new: + # Delete row. + if row: + del table.rows[uuid] +- changed = True +- self.notify(ROW_DELETE, row) ++ return Notice(ROW_DELETE, row) + else: + # XXX rate-limit + vlog.warn("cannot delete missing row %s from table %s" +@@ -723,7 +732,7 @@ class Idl(object): + if op == ROW_CREATE: + table.rows[uuid] = row + if changed: +- self.notify(ROW_CREATE, row) ++ return Notice(ROW_CREATE, row) + else: + op = ROW_UPDATE + if not row: +@@ -737,8 +746,8 @@ class Idl(object): + if op == ROW_CREATE: + table.rows[uuid] = row + if changed: +- self.notify(op, row, Row.from_json(self, table, uuid, old)) +- return changed ++ return Notice(op, row, Row.from_json(self, table, uuid, old)) ++ return False + + def __check_server_db(self): + """Returns True if this is a valid server database, False otherwise.""" +@@ -1567,10 +1576,9 @@ class Transaction(object): for col, val in row._mutations['_inserts'].items(): column = row._table.columns[col] if column.type.is_map(): @@ -43709,6 +44340,19 @@ index c94f2f5358..15eec6d4c0 100644 # For RHEL 7.2, 7.4, 7.6, 7.7, and 7.8 if [ -x "%{_datadir}/openvswitch/scripts/ovs-kmod-manage.sh" ]; then %{_datadir}/openvswitch/scripts/ovs-kmod-manage.sh +diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in +index b0383ed75e..ee8b3c9eac 100644 +--- a/rhel/openvswitch.spec.in ++++ b/rhel/openvswitch.spec.in +@@ -39,7 +39,7 @@ BuildRequires: checkpolicy, selinux-policy-devel + BuildRequires: autoconf, automake, libtool + BuildRequires: python3-sphinx + BuildRequires: unbound-devel +-BuildRequires: unwind-devel ++BuildRequires: libunwind-devel + + %bcond_without check + %bcond_with check_datapath_kernel diff --git a/rhel/usr_lib_systemd_system_ovsdb-server.service b/rhel/usr_lib_systemd_system_ovsdb-server.service index 4c170c09b4..98338b9dfb 100644 --- a/rhel/usr_lib_systemd_system_ovsdb-server.service @@ -43779,10 +44423,20 @@ index 2adaf231fe..beb0ab0d66 100644 allow openvswitch_load_module_t modules_object_t:dir { getattr open read search }; allow openvswitch_load_module_t openvswitch_load_module_exec_t:file { entrypoint }; diff --git a/tests/automake.mk b/tests/automake.mk -index 9c7ebdce9b..3d90f97687 100644 +index 9c7ebdce9b..d51d175f40 100644 --- a/tests/automake.mk +++ b/tests/automake.mk -@@ -152,7 +152,8 @@ SYSTEM_KMOD_TESTSUITE_AT = \ +@@ -132,7 +132,8 @@ FUZZ_REGRESSION_TESTS = \ + tests/fuzz-regression/ofp_print_fuzzer-5722747668791296 \ + tests/fuzz-regression/ofp_print_fuzzer-6285128790704128 \ + tests/fuzz-regression/ofp_print_fuzzer-6470117922701312 \ +- tests/fuzz-regression/ofp_print_fuzzer-6502620041576448 ++ tests/fuzz-regression/ofp_print_fuzzer-6502620041576448 \ ++ tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 + $(srcdir)/tests/fuzz-regression-list.at: tests/automake.mk + $(AM_V_GEN)for name in $(FUZZ_REGRESSION_TESTS); do \ + basename=`echo $$name | sed 's,^.*/,,'`; \ +@@ -152,7 +153,8 @@ SYSTEM_KMOD_TESTSUITE_AT = \ SYSTEM_USERSPACE_TESTSUITE_AT = \ tests/system-userspace-testsuite.at \ tests/system-userspace-macros.at \ @@ -43861,8 +44515,26 @@ index 88818618be..cdcd72c156 100644 +]) +OVS_VSWITCHD_STOP +AT_CLEANUP +diff --git a/tests/daemon.at b/tests/daemon.at +index a7982de381..39d9aa391e 100644 +--- a/tests/daemon.at ++++ b/tests/daemon.at +@@ -218,11 +218,11 @@ OVS_WAIT_UNTIL([test -s ovsdb-server.pid]) + OVS_WAIT_UNTIL([sc query ovsdb-server | grep STATE | grep RUNNING > /dev/null 2>&1]) + AT_CHECK([kill -0 `cat ovsdb-server.pid`], [0], [ignore]) + AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs], [0], +-[Open_vSwitch ++[_Server + ]) + AT_CHECK([sc stop ovsdb-server], [0], [ignore]) + OVS_WAIT_UNTIL([test ! -s ovsdb-server.pid]) +-AT_CHECK([sc query ovsdb-server | grep STATE | grep STOPPED], [0], [ignore]) ++OVS_WAIT_UNTIL([sc query ovsdb-server | grep STATE | grep STOPPED > /dev/null 2>&1]) + AT_CHECK([sc delete ovsdb-server], [0], [[[SC]] DeleteService SUCCESS + ]) + AT_CLEANUP diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at -index 0aeb4e788f..1651e02d29 100644 +index 0aeb4e788f..82a23d0cae 100644 --- a/tests/dpif-netdev.at +++ b/tests/dpif-netdev.at @@ -371,7 +371,7 @@ m4_define([DPIF_NETDEV_FLOW_HW_OFFLOAD], @@ -43937,6 +44609,39 @@ index 0aeb4e788f..1651e02d29 100644 ]) # Check that ip address and udp port were correctly modified in output packets. +@@ -506,3 +506,20 @@ udp,in_port=ANY,dl_vlan=99,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09: + + DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS([dummy]) + DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS([dummy-pmd]) ++ ++AT_SETUP([dpif-netdev - check dpctl/add-flow in_port exact match]) ++OVS_VSWITCHD_START( ++ [add-port br0 p1 \ ++ -- set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p0.sock \ ++ -- set bridge br0 datapath-type=dummy \ ++ other-config:datapath-id=1234 fail-mode=secure]) ++ ++AT_CHECK([ovs-appctl dpctl/add-flow "eth(),eth_type(0x0800),ipv4()" "3"], [2], ++[], [dnl ++ovs-vswitchd: updating flow table (Invalid argument) ++ovs-appctl: ovs-vswitchd: server returned an error ++]) ++OVS_WAIT_UNTIL([grep "flow: in_port is not an exact match" ovs-vswitchd.log]) ++OVS_VSWITCHD_STOP(["/flow: in_port is not an exact match/d ++/failed to put/d"]) ++AT_CLEANUP +diff --git a/tests/fuzz-regression-list.at b/tests/fuzz-regression-list.at +index e3173fb88f..2347c690ef 100644 +--- a/tests/fuzz-regression-list.at ++++ b/tests/fuzz-regression-list.at +@@ -21,3 +21,4 @@ TEST_FUZZ_REGRESSION([ofp_print_fuzzer-5722747668791296]) + TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6285128790704128]) + TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6470117922701312]) + TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6502620041576448]) ++TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6540965472632832]) +diff --git a/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 b/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 +new file mode 100644 +index 0000000000..e69de29bb2 diff --git a/tests/idltest.ovsschema b/tests/idltest.ovsschema index bee79fc50f..3ddb612b0c 100644 --- a/tests/idltest.ovsschema @@ -44259,6 +44964,41 @@ index 55c7a6e179..c8babe3612 100644 AT_CHECK([RUN_OVS_VSCTL([-- --id=@m create Datapath datapath_version=0 'capabilities={recirc=true}' -- set Open_vSwitch . datapaths:"system"=@m])], [0], [stdout]) AT_CHECK([RUN_OVS_VSCTL([list-dp-cap system])], [0], [recirc=true ]) +diff --git a/tests/ovsdb-client.at b/tests/ovsdb-client.at +index 8d777a0275..5e3b26aea8 100644 +--- a/tests/ovsdb-client.at ++++ b/tests/ovsdb-client.at +@@ -12,6 +12,30 @@ AT_CHECK([ovsdb-client get-schema-cksum unix:socket ordinals], [0], [12345678 9 + OVSDB_SERVER_SHUTDOWN + AT_CLEANUP + ++AT_SETUP([ovsdb-client needs-conversion (no conversion needed)]) ++AT_KEYWORDS([ovsdb client file positive]) ++ordinal_schema > schema ++touch .db.~lock~ ++AT_CHECK([ovsdb-tool create db schema], [0], [], [ignore]) ++AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore]) ++AT_CHECK([ovsdb-client needs-conversion unix:socket schema], [0], [no ++]) ++OVSDB_SERVER_SHUTDOWN ++AT_CLEANUP ++ ++AT_SETUP([ovsdb-client needs-conversion (conversion needed)]) ++AT_KEYWORDS([ovsdb client file positive]) ++ordinal_schema > schema ++touch .db.~lock~ ++AT_CHECK([ovsdb-tool create db schema], [0], [], [ignore]) ++AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore]) ++sed 's/5\.1\.3/5.1.4/' < schema > schema2 ++AT_CHECK([diff schema schema2], [1], [ignore]) ++AT_CHECK([ovsdb-client needs-conversion unix:socket schema2], [0], [yes ++]) ++OVSDB_SERVER_SHUTDOWN ++AT_CLEANUP ++ + AT_SETUP([ovsdb-client backup and restore]) + AT_KEYWORDS([ovsdb client positive]) + diff --git a/tests/ovsdb-cluster.at b/tests/ovsdb-cluster.at index 3a0bd4579e..92aa427093 100644 --- a/tests/ovsdb-cluster.at @@ -44466,7 +45206,7 @@ index 3a0bd4579e..92aa427093 100644 done=0 for j in $(seq 0 $(expr $n1 - 1)); do diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at -index cc38d69c10..8a28dfe4ca 100644 +index cc38d69c10..d0feaa31fe 100644 --- a/tests/ovsdb-idl.at +++ b/tests/ovsdb-idl.at @@ -12,25 +12,6 @@ ovsdb_start_idltest () { @@ -44707,7 +45447,36 @@ index cc38d69c10..8a28dfe4ca 100644 m4_define([OVSDB_CHECK_IDL_PARTIAL_UPDATE_SET_COLUMN], [AT_SETUP([$1 - C]) AT_KEYWORDS([ovsdb server idl partial update set column positive $5]) -@@ -1764,33 +1898,25 @@ OVSDB_CHECK_IDL_COMPOUND_INDEX_WITH_REF([set, simple3 idl-compound-index-with-re +@@ -1352,6 +1486,28 @@ m4_define([OVSDB_CHECK_IDL_NOTIFY], + [OVSDB_CHECK_IDL_PY([$1], [], [$2], [$3], [notify $4], [$5]) + OVSDB_CHECK_IDL_SSL_PY([$1], [], [$2], [$3], [notify $4], [$5])]) + ++OVSDB_CHECK_IDL_NOTIFY([simple link idl verify notify], ++ [['track-notify' \ ++ '["idltest", ++ {"op": "insert", ++ "table": "link1", ++ "row": {"i": 1, "k": ["named-uuid", "l1row"], "l2": ["set", [["named-uuid", "l2row"]]]}, ++ "uuid-name": "l1row"}, ++ {"op": "insert", ++ "table": "link2", ++ "uuid-name": "l2row", ++ "row": {"i": 2, "l1": ["set", [["named-uuid", "l1row"]]]}}]']], ++[[000: empty ++000: event:create, row={uuid=<0>}, updates=None ++000: event:create, row={uuid=<1>}, updates=None ++001: {"error":null,"result":[{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]} ++002: event:create, row={i=1 uuid=<2> l2=[<3>]}, updates=None ++002: event:create, row={i=2 uuid=<3> l1=[<2>]}, updates=None ++002: i=1 k=1 ka=[] l2=2 uuid=<2> ++002: i=2 l1=1 uuid=<3> ++003: done ++]]) ++ + OVSDB_CHECK_IDL_NOTIFY([simple idl verify notify], + [['track-notify' \ + '["idltest", +@@ -1764,33 +1920,25 @@ OVSDB_CHECK_IDL_COMPOUND_INDEX_WITH_REF([set, simple3 idl-compound-index-with-re ]]) m4_define([CHECK_STREAM_OPEN_BLOCK], @@ -44755,7 +45524,7 @@ index cc38d69c10..8a28dfe4ca 100644 # same as OVSDB_CHECK_IDL but uses Python IDL implementation with tcp # with multiple remotes to assert the idl connects to the leader of the Raft cluster -@@ -1798,7 +1924,7 @@ m4_define([OVSDB_CHECK_IDL_LEADER_ONLY_PY], +@@ -1798,7 +1946,7 @@ m4_define([OVSDB_CHECK_IDL_LEADER_ONLY_PY], [AT_SETUP([$1 - Python3 (leader only)]) AT_KEYWORDS([ovsdb server idl Python leader_only with tcp socket]) m4_define([LPBK],[127.0.0.1]) @@ -44764,7 +45533,7 @@ index cc38d69c10..8a28dfe4ca 100644 PARSE_LISTENING_PORT([s2.log], [TCP_PORT_1]) PARSE_LISTENING_PORT([s3.log], [TCP_PORT_2]) PARSE_LISTENING_PORT([s1.log], [TCP_PORT_3]) -@@ -1814,3 +1940,59 @@ m4_define([OVSDB_CHECK_IDL_LEADER_ONLY_PY], +@@ -1814,3 +1962,59 @@ m4_define([OVSDB_CHECK_IDL_LEADER_ONLY_PY], OVSDB_CHECK_IDL_LEADER_ONLY_PY([Check Python IDL connects to leader], 3, ['remote']) OVSDB_CHECK_IDL_LEADER_ONLY_PY([Check Python IDL reconnects to leader], 3, ['remote' '+remotestop' 'remote']) @@ -44860,6 +45629,23 @@ index 328ae2bc9d..49ac45275a 100755 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. +diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at +index 68c8774d1a..9d5e24a292 100644 +--- a/tests/system-common-macros.at ++++ b/tests/system-common-macros.at +@@ -275,6 +275,12 @@ m4_define([OVS_START_L7], + ] + ) + ++# OFPROTO_CLEAR_DURATION_IDLE([]) ++# ++# Clear the duration from the piped input which would differ from test to test ++# ++m4_define([OFPROTO_CLEAR_DURATION_IDLE], [[sed -e 's/duration=.*s,/duration=,/g' -e 's/idle_age=[0-9]*,/idle_age=,/g']]) ++ + # OVS_CHECK_VXLAN() + # + # Do basic check for vxlan functionality, skip the test if it's not there. diff --git a/tests/system-route.at b/tests/system-route.at new file mode 100644 index 0000000000..1714273e35 @@ -44895,7 +45681,7 @@ index 0000000000..1714273e35 +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/system-traffic.at b/tests/system-traffic.at -index 4a39c929c2..3ed03d92b5 100644 +index 4a39c929c2..da61e4cae8 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -611,6 +611,16 @@ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 10.1.1.100 | FORMAT_PING], [0], [dnl @@ -44915,6 +45701,93 @@ index 4a39c929c2..3ed03d92b5 100644 OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP +@@ -2331,6 +2341,35 @@ NXST_FLOW reply: + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP + ++AT_SETUP([conntrack - generic IP protocol]) ++CHECK_CONNTRACK() ++OVS_TRAFFIC_VSWITCHD_START() ++AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg ofproto_dpif_upcall:dbg]) ++ ++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 ++table=0, priority=1,action=drop ++table=0, priority=10,arp,action=normal ++table=0, priority=100,ip,action=ct(table=1) ++table=1, priority=100,in_port=1,ip,ct_state=+trk+new,action=ct(commit) ++table=1, priority=100,in_port=1,ct_state=+trk+est,action=normal ++]) ++ ++AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) ++ ++AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=01005e00001200005e000101080045c0002800000000ff7019cdc0a8001ee0000012210164010001ba52c0a800010000000000000000000000000000 actions=resubmit(,0)"]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=192\.168\.0\.30,"], [], [dnl ++112,orig=(src=192.168.0.30,dst=224.0.0.18,sport=0,dport=0),reply=(src=224.0.0.18,dst=192.168.0.30,sport=0,dport=0) ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_SETUP([conntrack - ICMP related]) + AT_SKIP_IF([test $HAVE_NC = no]) + CHECK_CONNTRACK() +@@ -5873,6 +5912,50 @@ ovs-appctl dpif/dump-flows br0 + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP + ++AT_SETUP([conntrack - Multiple ICMP traverse]) ++dnl This tracks sending ICMP packets via conntrack multiple times for the ++dnl same packet ++CHECK_CONNTRACK() ++OVS_TRAFFIC_VSWITCHD_START() ++OVS_CHECK_CT_CLEAR() ++ ++ADD_NAMESPACES(at_ns0, at_ns1) ++ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01") ++ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02") ++dnl setup ct flows ++AT_DATA([flows.txt], [dnl ++table=0,priority=10 ip,icmp,ct_state=-trk action=ct(zone=1,table=1) ++table=0,priority=0 action=drop ++table=1,priority=10 ct_state=-est+trk+new,ip,ct_zone=1,in_port=1 action=ct(commit,table=2) ++table=1,priority=10 ct_state=+est-new+trk,ct_zone=1,in_port=1 action=resubmit(,2) ++table=1,priority=0 action=drop ++table=2,priority=10 ct_state=+trk+new,in_port=1 action=drop ++table=2,priority=10 ct_state=+trk+est action=drop ++]) ++ ++AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) ++ ++# sending icmp pkts, first and second ++NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f0 00 00 01 01 02 f0 00 00 01 01 01 08 00 45 00 00 1c 00 01 00 00 40 01 64 dc 0a 01 01 01 0a 01 01 02 08 00 f7 ff ff ff ff ff > /dev/null]) ++ ++NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f0 00 00 01 01 02 f0 00 00 01 01 01 08 00 45 00 00 1c 00 01 00 00 40 01 64 dc 0a 01 01 01 0a 01 01 02 08 00 f7 ff ff ff ff ff > /dev/null]) ++ ++sleep 1 ++ ++dnl ensure CT picked up the packet ++AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1)], [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) ++]) ++ ++AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE], ++ [0], [dnl ++ cookie=0x0, duration=, table=2, n_packets=2, n_bytes=84, idle_age=, priority=10,ct_state=+new+trk,in_port=1 actions=drop ++ cookie=0x0, duration=, table=2, n_packets=0, n_bytes=0, idle_age=, priority=10,ct_state=+est+trk actions=drop ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_BANNER([802.1ad]) + + AT_SETUP([802.1ad - vlan_limit]) diff --git a/tests/system-userspace-packet-type-aware.at b/tests/system-userspace-packet-type-aware.at index c2246316de..974304758f 100644 --- a/tests/system-userspace-packet-type-aware.at @@ -45160,7 +46033,7 @@ index b1a4be36bb..31513c537f 100644 } else { print_idl(idl, step++); diff --git a/tests/test-ovsdb.py b/tests/test-ovsdb.py -index 1b94b79a07..a196802743 100644 +index 1b94b79a07..9d3228f234 100644 --- a/tests/test-ovsdb.py +++ b/tests/test-ovsdb.py @@ -28,6 +28,7 @@ import ovs.util @@ -45171,17 +46044,31 @@ index 1b94b79a07..a196802743 100644 from ovs.fatal_signal import signal_alarm vlog = ovs.vlog.Vlog("test-ovsdb") -@@ -159,7 +160,8 @@ def get_simple_printable_row_string(row, columns): +@@ -159,7 +160,10 @@ def get_simple_printable_row_string(row, columns): is ovs.db.data.Atom): value = getattr(row, column) if isinstance(value, dict): - value = sorted(value.items()) + value = sorted((row_to_uuid(k), row_to_uuid(v)) + for k, v in value.items()) ++ if isinstance(value, (list, tuple)): ++ value = sorted((row_to_uuid(v) for v in value)) s += "%s=%s " % (column, value) s = s.strip() s = re.sub('""|,|u?\'', "", s) -@@ -212,6 +214,14 @@ def print_idl(idl, step): +@@ -170,9 +174,10 @@ def get_simple_printable_row_string(row, columns): + return s + + +-def get_simple_table_printable_row(row): ++def get_simple_table_printable_row(row, *additional_columns): + simple_columns = ["i", "r", "b", "s", "u", "ia", + "ra", "ba", "sa", "ua", "uuid"] ++ simple_columns.extend(additional_columns) + return get_simple_printable_row_string(row, simple_columns) + + +@@ -212,6 +217,14 @@ def print_idl(idl, step): print(s) n += 1 @@ -45196,7 +46083,7 @@ index 1b94b79a07..a196802743 100644 if "link1" in idl.tables: l1 = idl.tables["link1"].rows for row in l1.values(): -@@ -303,6 +313,11 @@ def idltest_find_simple3(idl, i): +@@ -303,6 +316,11 @@ def idltest_find_simple3(idl, i): return next(idl.index_equal("simple3", "simple3_by_name", i), None) @@ -45208,7 +46095,7 @@ index 1b94b79a07..a196802743 100644 def idl_set(idl, commands, step): txn = ovs.db.idl.Transaction(idl) increment = False -@@ -524,6 +539,12 @@ def idl_set(idl, commands, step): +@@ -524,6 +542,12 @@ def idl_set(idl, commands, step): setattr(new_row3, 'name', 'String3') new_row3.addvalue('uset', new_row41.uuid) assert len(getattr(new_row3, 'uset', [])) == 1 @@ -45221,6 +46108,16 @@ index 1b94b79a07..a196802743 100644 else: sys.stderr.write("unknown command %s\n" % name) sys.exit(1) +@@ -616,7 +640,8 @@ def do_idl(schema_file, remote, *commands): + def mock_notify(event, row, updates=None): + output = "%03d: " % step + output += "event:" + str(event) + ", row={" +- output += get_simple_table_printable_row(row) + "}, updates=" ++ output += get_simple_table_printable_row(row, ++ 'l2', 'l1') + "}, updates=" + if updates is None: + output += "None" + else: diff --git a/tests/test-reconnect.c b/tests/test-reconnect.c index 5a14e7fe58..bf0463e25c 100644 --- a/tests/test-reconnect.c @@ -45542,7 +46439,7 @@ index e55bfc2ed5..987d211069 100755 diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in -index 8c5cd70327..d71c34e691 100644 +index 8c5cd70327..4156da20ef 100644 --- a/utilities/ovs-ctl.in +++ b/utilities/ovs-ctl.in @@ -43,7 +43,8 @@ set_hostname () { @@ -45555,7 +46452,15 @@ index 8c5cd70327..d71c34e691 100644 } set_system_ids () { -@@ -230,9 +231,14 @@ start_forwarding () { +@@ -225,14 +226,21 @@ start_forwarding () { + if test X"$OVS_VSWITCHD" = Xyes; then + do_start_forwarding || return 1 + fi +- set_hostname & ++ if test X"$RECORD_HOSTNAME" = Xyes; then ++ set_hostname & ++ fi + return 0 } start_ovs_ipsec () { @@ -45570,7 +46475,7 @@ index 8c5cd70327..d71c34e691 100644 --log-file --detach --monitor unix:${rundir}/db.sock || return 1 return 0 } -@@ -254,8 +260,7 @@ stop_forwarding () { +@@ -254,8 +262,7 @@ stop_forwarding () { } stop_ovs_ipsec () { @@ -45580,7 +46485,15 @@ index 8c5cd70327..d71c34e691 100644 } ## --------------- ## -@@ -341,6 +346,7 @@ set_defaults () { +@@ -312,6 +319,7 @@ set_defaults () { + SYSTEM_ID= + + FULL_HOSTNAME=yes ++ RECORD_HOSTNAME=yes + + DELETE_BRIDGES=no + DELETE_TRANSIENT_PORTS=no +@@ -341,6 +349,7 @@ set_defaults () { SPORT= IKE_DAEMON= @@ -45588,7 +46501,54 @@ index 8c5cd70327..d71c34e691 100644 type_file=$etcdir/system-type.conf version_file=$etcdir/system-version.conf -@@ -424,6 +430,8 @@ Options for "enable-protocol": +@@ -372,19 +381,24 @@ This program is intended to be invoked internally by Open vSwitch startup + scripts. System administrators should not normally invoke it directly. + + Commands: +- start start Open vSwitch daemons +- stop stop Open vSwitch daemons +- restart stop and start Open vSwitch daemons +- status check whether Open vSwitch daemons are running +- version print versions of Open vSwitch daemons +- load-kmod insert modules if not already present +- force-reload-kmod save OVS network device state, stop OVS, unload kernel +- module, reload kernel module, start OVS, restore state +- enable-protocol enable protocol specified in options with iptables +- delete-transient-ports delete transient (other_config:transient=true) ports +- start-ovs-ipsec start Open vSwitch ipsec daemon +- stop-ovs-ipsec stop Open vSwitch ipsec daemon +- help display this help message ++ start start Open vSwitch daemons ++ stop stop Open vSwitch daemons ++ restart stop and start Open vSwitch daemons ++ status check whether Open vSwitch daemons are running ++ version print versions of Open vSwitch daemons ++ load-kmod insert modules if not already present ++ force-reload-kmod save OVS network device state, stop OVS, unload ++ kernel module, reload kernel module, start OVS, ++ restore state ++ enable-protocol enable protocol specified in options with ++ iptables ++ delete-transient-ports delete transient (other_config:transient=true) ++ ports ++ start-ovs-ipsec start Open vSwitch ipsec daemon ++ stop-ovs-ipsec stop Open vSwitch ipsec daemon ++ record-hostname-if-not-set determine the system hostname and record it in ++ the Open vSwitch database if not already set ++ help display this help message + + One of the following options is required for "start", "restart" and "force-reload-kmod": + --system-id=UUID set specific ID to uniquely identify this system +@@ -405,6 +419,8 @@ Less important options for "start", "restart" and "force-reload-kmod": + --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY) + --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY) + --no-full-hostname set short hostname instead of full hostname ++ --no-record-hostname do not attempt to determine/record system ++ hostname as part of start command + + Debugging options for "start", "restart" and "force-reload-kmod": + --ovsdb-server-wrapper=WRAPPER +@@ -424,6 +440,8 @@ Options for "enable-protocol": Option for "start-ovs-ipsec": --ike-daemon=IKE_DAEMON the IKE daemon for ipsec tunnels (either libreswan or strongswan) @@ -45597,6 +46557,16 @@ index 8c5cd70327..d71c34e691 100644 Other options: -h, --help display this help message +@@ -561,6 +579,9 @@ case $command in + stop-ovs-ipsec) + stop_ovs_ipsec + ;; ++ record-hostname-if-not-set) ++ set_hostname ++ ;; + help) + usage + ;; diff --git a/utilities/ovs-dev.py b/utilities/ovs-dev.py index 248d22ab9a..c45788acd5 100755 --- a/utilities/ovs-dev.py @@ -45728,7 +46698,7 @@ index e591c26a6c..ce348b9d16 100644 } diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml -index 3ddaaefda8..9f07ec9b22 100644 +index 3ddaaefda8..11880f1d2f 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -653,8 +653,9 @@ @@ -45776,6 +46746,37 @@ index 3ddaaefda8..9f07ec9b22 100644

+@@ -2971,8 +2998,8 @@ + +

+ Setting any of these options enables IPsec support for a given +- tunnel. gre, ip6gre, +- geneve, vxlan and stt ++ tunnel. gre, geneve, ++ vxlan and stt + interfaces support these options. See the IPsec + section in the table for a description + of each mode. +@@ -4530,7 +4557,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ + packets per second the CIR would be set to to to 46000000. This value + can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing + rate for the number of packets per second and 46 represents the size +- of the packet data for a 64 byte ip packet. ++ of the packet data for a 64 bytes IP packet without 14 bytes Ethernet ++ and 4 bytes FCS header. + + + The Committed Burst Size (CBS) is measured in bytes and represents a +@@ -4551,7 +4579,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ + packets per second the EIR would be set to to to 46000000. This value + can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing + rate for the number of packets per second and 46 represents the size +- of the packet data for a 64 byte ip packet. ++ of the packet data for a 64 bytes IP packet without 14 bytes Ethernet ++ and 4 bytes FCS header. + + + The Excess Burst Size (EBS) is measured in bytes and represents a diff --git a/xenserver/etc_xapi.d_plugins_openvswitch-cfg-update b/xenserver/etc_xapi.d_plugins_openvswitch-cfg-update index e7404e3b00..b8db881949 100755 --- a/xenserver/etc_xapi.d_plugins_openvswitch-cfg-update diff --git a/SPECS/openvswitch2.13.spec b/SPECS/openvswitch2.13.spec index 0dfc738..1cca3d4 100644 --- a/SPECS/openvswitch2.13.spec +++ b/SPECS/openvswitch2.13.spec @@ -59,7 +59,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.13.0 -Release: 79.5.1%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} +Release: 96%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -332,7 +332,14 @@ make V=1 O=%{dpdktarget} T=%{dpdktarget} %{?_smp_mflags} config cp -f %{SOURCE500} %{SOURCE502} "%{_sourcedir}/%{dpdktarget}-config" . %{SOURCE502} %{dpdktarget}-config "%{dpdktarget}/.config" -make V=1 O=%{dpdktarget} %{?_smp_mflags} +# Currently RHEL8.3+ includes binutils 2.30 with the patch to fix AVX512 support backported (#1870039), +# but DPDK 19.11 blindly disables AVX512 support if ld version < 2.32 +binutils_version=$(rpm -q --qf '%%{version}-%%{release}' binutils) +if [ "$binutils_version" "<" "2.30-79.el8" ]; then + make V=1 O=%{dpdktarget} %{?_smp_mflags} +else + make LD_VERSION=2.32 V=1 O=%{dpdktarget} %{?_smp_mflags} +fi # Generate a list of supported drivers, its hard to tell otherwise. cat << EOF > README.DPDK-PMDS @@ -703,25 +710,73 @@ exit 0 %endif %changelog -* Thu Feb 04 2021 Timothy Redaelli - 2.13.0-79.5 -- lldp: do not leak memory on multiple instances of TLVs - [5a1158c1bbca87260491048219d08189b2367797] +* Tue Mar 16 2021 Open vSwitch CI - 2.13.0-96 +- Merging upstream branch-2.13 + [bb107a7f7f27a7f3ad77cebc15049606e63568c2] + +* Mon Feb 15 2021 Eelco Chaudron - 2.13.0-95 +- conntrack: add generic IP protocol support + [6b3ca4b0282bb6e728066004fca47a0936e4b8c3] -* Thu Feb 04 2021 Timothy Redaelli - 2.13.0-79.4 -- flow: Support extra padding length. - [c9ada1e1249d7729954c4154f0cc7bd375f40686] +* Wed Feb 10 2021 Open vSwitch CI - 2.13.0-94 +- Merging upstream branch-2.13 + [8655a639ac7db93d02e3cd003cf5ae4f7acad10a] + +* Fri Feb 05 2021 Open vSwitch CI - 2.13.0-93 +- Merging upstream branch-2.13 + [2100324b58f204f956a35e9827d2d72e4d20b7d9] -* Tue Feb 02 2021 Timothy Redaelli - 2.13.0-79.3 +* Thu Feb 04 2021 Open vSwitch CI - 2.13.0-92 +- Merging upstream branch-2.13 + [92b77d14894afeb17d2b139e75670aaa29853511] + +* Wed Feb 03 2021 Open vSwitch CI - 2.13.0-91 +- Merging upstream branch-2.13 + [ea87c21ff21477eff945b07a755329f05d4466b7] + +* Tue Feb 02 2021 Timothy Redaelli - 2.13.0-90 - dpif-netdev: Add PMD auto load balance status log. - [793de3fd0a2b32dc7f45d4e9f01daa419b144013] + [4fd540d8efc8369c6af05e5e266bf418afade8d3] -* Tue Feb 02 2021 Timothy Redaelli - 2.13.0-79.2 +* Tue Feb 02 2021 Timothy Redaelli - 2.13.0-89 - dpif-netdev: Add parameters to configure PMD auto load balance. - [75555d8352c7151ec5dd02653ac820229775caf2] + [5935f7a9d8754ff0b5fadbc835c65dea9cdf1434] -* Tue Feb 02 2021 Timothy Redaelli - 2.13.0-79.1 +* Tue Feb 02 2021 Timothy Redaelli - 2.13.0-88 - dpif-netdev: Add log for PMD auto load balance interval parameter. - [f22c01de8773a60069e2371fb110fc207756dcd4] + [a8f4696c200ee9f1786b66fe6c7d7da4caa9924c] + +* Mon Feb 01 2021 Open vSwitch CI - 2.13.0-87 +- Merging upstream branch-2.13 + [d303f53850951fa26f6a832ffb2f437fcd4cf9f1] + +* Fri Jan 29 2021 Open vSwitch CI - 2.13.0-86 +- Merging upstream branch-2.13 + [2986e0866ea3d2c5e9a4b4fd43e81e1477c03686] + +* Thu Jan 28 2021 Open vSwitch CI - 2.13.0-85 +- Merging upstream branch-2.13 + [f2f6b58dd9df37438da9c7ef902decd613c787d6] + +* Thu Jan 28 2021 Timothy Redaelli - 2.13.0-84 +- redhat: Use a mock config based on the buildsystem target + [b820a7b8946c64749284b88538399dd2f9b411fe] + +* Thu Jan 28 2021 Flavio Leitner - 2.13.0-83 +- Merging b37528cef7 conntrack: Fix the icmp conntrack new state. + [dc913c7d4c23e792d4077c81bc65c025bc4c5f6c] + +* Thu Jan 28 2021 Flavio Leitner - 2.13.0-82 +- Merging f383000ca6 acinclude: Strip out -mno-avx512f provided .. + [304ba372e44e1f930d6a2134140db415d8d56922] + +* Wed Jan 20 2021 Timothy Redaelli - 2.13.0-81 +- Enable AVX512 support on binutils >= 2.30-79.el8 + [8b3f9929026f45837b5670fade0ffde616fde5bc] + +* Thu Jan 14 2021 Open vSwitch CI - 2.13.0-80 +- Merging upstream branch-2.13 + [b7a6e48410649f2d0029baaf499a5cf0619f4f34] * Wed Jan 06 2021 Open vSwitch CI - 2.13.0-79 - Merging upstream branch-2.13