From 0c058e5eed2f9d87b78881ea9f505cbcd68c26f9 Mon Sep 17 00:00:00 2001 From: openeuler-netdev Date: Thu, 26 Dec 2019 22:17:49 +0800 Subject: [PATCH] update patch --- ...ate-statistics-in-offload-implementa.patch | 127 ++ ...on-Fix-security-mailing-list-address.patch | 28 + Prepare-for-2.12.1.patch | 55 + cirrus-Use-FreeBSD-12.1-stable-release.patch | 31 + cirrus-Use-latest-stable-FreeBSD-images.patch | 43 + compat-Add-compat-fix-for-old-kernels.patch | 50 + ...eck_orig_tuple-Valgrind-false-positi.patch | 55 + ...reverse_nat_packet-variable-datatype.patch | 53 + ...te-accessing-of-conntrack-data-in-pk.patch | 102 ++ ...-Backports-bugfixes-for-nf_conncount.patch | 682 +++++++ db-ctl-base-Free-leaked-ovsdb_datum.patch | 81 + ...-struct-ub_result-when-callback-retu.patch | 69 + ...incorrect-reference-for-dpdk-testpmd.patch | 44 + ...earing-copying-of-memory-layout-flag.patch | 69 + dpdk-Use-DPDK-18.11.5-release.patch | 107 ++ ...d-infinite-re-addition-of-misconfigu.patch | 112 ++ ...ot-mix-recirculation-depth-into-RSS-.patch | 43 + ...time-delta-overflow-in-case-of-race-.patch | 48 + ...le-uninitialized-value-error-for-mat.patch | 53 + dpif-netlink-Free-leaked-nl_sock.patch | 49 + ...-OVS-DPDK-version-table-for-OVS-2.12.patch | 29 + ...te-list-of-kernels-supported-by-2.12.patch | 27 + ...eader-parser-with-partial-offloading.patch | 34 + ...n-vlan-packets-with-partial-offloadi.patch | 186 ++ ...ointer-to-member-of-packed-struct-ic.patch | 256 +++ ...ct-padding-length-checking-in-ipv6_s.patch | 33 + ...bail-out-when-ipf-state-is-COMPLETED.patch | 41 + ...e-input-buffer-size-from-512-to-4096.patch | 32 + ...ry-leak-of-lflow_ref_list_node-ref_n.patch | 50 + ...x-flow-dump-for-tunnel-id-equal-zero.patch | 32 + ...-crashes-when-a-LLDP-enabled-port-is.patch | 78 + ...id-removing-of-XDP-program-if-not-lo.patch | 61 + ...-umem-creation-failure-due-to-uninit.patch | 37 + ...ate-memory-locking-limits-unconditio.patch | 59 + ...pdk-Fix-flow-control-not-configuring.patch | 76 + netdev-dpdk-Fix-padding-info-comment.patch | 44 + ...h-on-PACKET_OUT-due-to-recursive-loc.patch | 259 +++ ...ow-IPv6-ND-Extensions-only-if-suppor.patch | 180 ++ ofproto-dpif-Free-leaked-webster.patch | 53 + ...nitialize-xlate_cache-to-free-resour.patch | 49 + ...te-Restore-table-ID-on-error-in-xlat.patch | 29 + ...a-typo-for-ttl-in-dpif_sflow_actions.patch | 28 + ofproto-fix-stack-buffer-overflow.patch | 102 ++ openvswitch-kmod.spec | 85 +- ...rt-and-outport-symbol-tables-from-co.patch | 124 ++ ...oneous-duplicate-IP-address-messages.patch | 54 + ...dd-missing-port-group-lflow-referenc.patch | 234 +++ ovs-ofctl-Free-leaked-minimatch.patch | 47 + ovsdb-client-Free-ovsdb_schema.patch | 43 + ...-Wait-until-leader-is-elected-before.patch | 59 + ...lection-timer-parsing-in-snapshot-RP.patch | 133 ++ ...he-problem-when-cluster-restarted-af.patch | 60 + ...-t-drop-all-connections-on-read-writ.patch | 92 + ...-memory-leak-while-converting-databa.patch | 61 + ...-fix-memory-leak-while-deleting-zone.patch | 63 + raft-Free-leaked-json-data.patch | 51 + ...d-manage.sh-that-may-create-invalid-.patch | 55 + ...ort-RHEL-7.8-kernel-module-rpm-build.patch | 78 + ...-Support-RHEL7.7-build-and-packaging.patch | 90 + ...-fedora.spec.in-Fix-output-redirect-.patch | 31 + ...-Get-rid-of-obsolete-rte_flow-header.patch | 1559 +++++++++++++++++ ...mportant-memory-leak-in-ssl_connect-.patch | 249 +++ ...Add-test-for-infinite-re-addition-of.patch | 74 + tc-Limit-the-max-action-number-to-16.patch | 87 + ...ation-in-userspace-packet-type-aware.patch | 93 + ...rop-MD-related-workaround-for-sparse.patch | 36 + trigger-Free-leaked-ovsdb_schema.patch | 51 + vswitch.xml-Fix-column-for-xdpmode.patch | 33 + 68 files changed, 7212 insertions(+), 6 deletions(-) create mode 100644 Avoid-indeterminate-statistics-in-offload-implementa.patch create mode 100644 Documentation-Fix-security-mailing-list-address.patch create mode 100644 Prepare-for-2.12.1.patch create mode 100644 cirrus-Use-FreeBSD-12.1-stable-release.patch create mode 100644 cirrus-Use-latest-stable-FreeBSD-images.patch create mode 100644 compat-Add-compat-fix-for-old-kernels.patch create mode 100644 conntrack-Fix-check_orig_tuple-Valgrind-false-positi.patch create mode 100644 conntrack-Fix-reverse_nat_packet-variable-datatype.patch create mode 100644 conntrack-Validate-accessing-of-conntrack-data-in-pk.patch create mode 100644 datapath-compat-Backports-bugfixes-for-nf_conncount.patch create mode 100644 db-ctl-base-Free-leaked-ovsdb_datum.patch create mode 100644 dns-resolve-Free-struct-ub_result-when-callback-retu.patch create mode 100644 doc-Fix-incorrect-reference-for-dpdk-testpmd.patch create mode 100644 dp-packet-Fix-clearing-copying-of-memory-layout-flag.patch create mode 100644 dpdk-Use-DPDK-18.11.5-release.patch create mode 100644 dpif-netdev-Avoid-infinite-re-addition-of-misconfigu.patch create mode 100644 dpif-netdev-Do-not-mix-recirculation-depth-into-RSS-.patch create mode 100644 dpif-netdev-Fix-time-delta-overflow-in-case-of-race-.patch create mode 100644 dpif-netdev-Handle-uninitialized-value-error-for-mat.patch create mode 100644 dpif-netlink-Free-leaked-nl_sock.patch create mode 100644 faq-Update-OVS-DPDK-version-table-for-OVS-2.12.patch create mode 100644 faq-Update-list-of-kernels-supported-by-2.12.patch create mode 100644 flow-Fix-IPv6-header-parser-with-partial-offloading.patch create mode 100644 flow-Fix-crash-on-vlan-packets-with-partial-offloadi.patch create mode 100644 flow-Fix-using-pointer-to-member-of-packed-struct-ic.patch create mode 100644 flow-fix-incorrect-padding-length-checking-in-ipv6_s.patch create mode 100644 ipf-bail-out-when-ipf-state-is-COMPLETED.patch create mode 100644 jsonrpc-increase-input-buffer-size-from-512-to-4096.patch create mode 100644 lflow.c-Fix-memory-leak-of-lflow_ref_list_node-ref_n.patch create mode 100644 lib-tc-Fix-flow-dump-for-tunnel-id-equal-zero.patch create mode 100644 lldp-Fix-for-OVS-crashes-when-a-LLDP-enabled-port-is.patch create mode 100644 netdev-afxdp-Avoid-removing-of-XDP-program-if-not-lo.patch create mode 100644 netdev-afxdp-Fix-umem-creation-failure-due-to-uninit.patch create mode 100644 netdev-afxdp-Update-memory-locking-limits-unconditio.patch create mode 100644 netdev-dpdk-Fix-flow-control-not-configuring.patch create mode 100644 netdev-dpdk-Fix-padding-info-comment.patch create mode 100644 ofproto-Fix-crash-on-PACKET_OUT-due-to-recursive-loc.patch create mode 100644 ofproto-dpif-Allow-IPv6-ND-Extensions-only-if-suppor.patch create mode 100644 ofproto-dpif-Free-leaked-webster.patch create mode 100644 ofproto-dpif-Uninitialize-xlate_cache-to-free-resour.patch create mode 100644 ofproto-dpif-xlate-Restore-table-ID-on-error-in-xlat.patch create mode 100644 ofproto-fix-a-typo-for-ttl-in-dpif_sflow_actions.patch create mode 100644 ofproto-fix-stack-buffer-overflow.patch create mode 100644 ovn-Exclude-inport-and-outport-symbol-tables-from-co.patch create mode 100644 ovn-Prevent-erroneous-duplicate-IP-address-messages.patch create mode 100644 ovn-controller-Add-missing-port-group-lflow-referenc.patch create mode 100644 ovs-ofctl-Free-leaked-minimatch.patch create mode 100644 ovsdb-client-Free-ovsdb_schema.patch create mode 100644 ovsdb-cluster.at-Wait-until-leader-is-elected-before.patch create mode 100644 ovsdb-raft-Fix-election-timer-parsing-in-snapshot-RP.patch create mode 100644 ovsdb-raft-Fix-the-problem-when-cluster-restarted-af.patch create mode 100644 ovsdb-server-Don-t-drop-all-connections-on-read-writ.patch create mode 100644 ovsdb-server-fix-memory-leak-while-converting-databa.patch create mode 100644 ovsdb-server-fix-memory-leak-while-deleting-zone.patch create mode 100644 raft-Free-leaked-json-data.patch create mode 100644 rhel-Fix-ovs-kmod-manage.sh-that-may-create-invalid-.patch create mode 100644 rhel-Support-RHEL-7.8-kernel-module-rpm-build.patch create mode 100644 rhel-Support-RHEL7.7-build-and-packaging.patch create mode 100644 rhel-openvswitch-fedora.spec.in-Fix-output-redirect-.patch create mode 100644 sparse-Get-rid-of-obsolete-rte_flow-header.patch create mode 100644 stream_ssl-fix-important-memory-leak-in-ssl_connect-.patch create mode 100644 system-afxdp.at-Add-test-for-infinite-re-addition-of.patch create mode 100644 tc-Limit-the-max-action-number-to-16.patch create mode 100644 tests-Fix-indentation-in-userspace-packet-type-aware.patch create mode 100644 travis-Drop-MD-related-workaround-for-sparse.patch create mode 100644 trigger-Free-leaked-ovsdb_schema.patch create mode 100644 vswitch.xml-Fix-column-for-xdpmode.patch diff --git a/Avoid-indeterminate-statistics-in-offload-implementa.patch b/Avoid-indeterminate-statistics-in-offload-implementa.patch new file mode 100644 index 0000000..208a1ea --- /dev/null +++ b/Avoid-indeterminate-statistics-in-offload-implementa.patch @@ -0,0 +1,127 @@ +From def4468defed9fb5418dc7311972b04ac3bf579a Mon Sep 17 00:00:00 2001 +From: Ben Pfaff +Date: Fri, 25 Oct 2019 11:46:24 -0700 +Subject: Avoid indeterminate statistics in offload implementations. + +A lot of the offload implementations didn't bother to initialize the +statistics they were supposed to return. I don't know whether any of +the callers actually use them, but it looked wrong. + +Found by inspection. + +Acked-by: Ilya Maximets +Signed-off-by: Ben Pfaff +--- + lib/netdev-dummy.c | 10 ++++++++-- + lib/netdev-offload-dpdk.c | 10 ++++++++-- + lib/netdev-offload-tc.c | 5 ++++- + 3 files changed, 20 insertions(+), 5 deletions(-) + +diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c +index f0c0fbae8..d2201420c 100644 +--- a/lib/netdev-dummy.c ++++ b/lib/netdev-dummy.c +@@ -1434,7 +1434,7 @@ netdev_dummy_flow_put(struct netdev *netdev, struct match *match, + struct nlattr *actions OVS_UNUSED, + size_t actions_len OVS_UNUSED, + const ovs_u128 *ufid, struct offload_info *info, +- struct dpif_flow_stats *stats OVS_UNUSED) ++ struct dpif_flow_stats *stats) + { + struct netdev_dummy *dev = netdev_dummy_cast(netdev); + struct offloaded_flow *off_flow; +@@ -1476,12 +1476,15 @@ netdev_dummy_flow_put(struct netdev *netdev, struct match *match, + ds_destroy(&ds); + } + ++ if (stats) { ++ memset(stats, 0, sizeof *stats); ++ } + return 0; + } + + static int + netdev_dummy_flow_del(struct netdev *netdev, const ovs_u128 *ufid, +- struct dpif_flow_stats *stats OVS_UNUSED) ++ struct dpif_flow_stats *stats) + { + struct netdev_dummy *dev = netdev_dummy_cast(netdev); + struct offloaded_flow *off_flow; +@@ -1521,6 +1524,9 @@ exit: + ds_destroy(&ds); + } + ++ if (stats) { ++ memset(stats, 0, sizeof *stats); ++ } + return error ? -1 : 0; + } + +diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c +index 01e900461..96794dc4d 100644 +--- a/lib/netdev-offload-dpdk.c ++++ b/lib/netdev-offload-dpdk.c +@@ -710,7 +710,7 @@ static int + netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, + struct nlattr *actions, size_t actions_len, + const ovs_u128 *ufid, struct offload_info *info, +- struct dpif_flow_stats *stats OVS_UNUSED) ++ struct dpif_flow_stats *stats) + { + struct rte_flow *rte_flow; + int ret; +@@ -732,13 +732,16 @@ netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, + return ret; + } + ++ if (stats) { ++ memset(stats, 0, sizeof *stats); ++ } + return netdev_offload_dpdk_add_flow(netdev, match, actions, + actions_len, ufid, info); + } + + static int + netdev_offload_dpdk_flow_del(struct netdev *netdev, const ovs_u128 *ufid, +- struct dpif_flow_stats *stats OVS_UNUSED) ++ struct dpif_flow_stats *stats) + { + struct rte_flow *rte_flow = ufid_to_rte_flow_find(ufid); + +@@ -746,6 +749,9 @@ netdev_offload_dpdk_flow_del(struct netdev *netdev, const ovs_u128 *ufid, + return -1; + } + ++ if (stats) { ++ memset(stats, 0, sizeof *stats); ++ } + return netdev_offload_dpdk_destroy_flow(netdev, ufid, rte_flow); + } + +diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c +index ad637b48c..a6b03015d 100644 +--- a/lib/netdev-offload-tc.c ++++ b/lib/netdev-offload-tc.c +@@ -1086,7 +1086,7 @@ static int + netdev_tc_flow_put(struct netdev *netdev, struct match *match, + struct nlattr *actions, size_t actions_len, + const ovs_u128 *ufid, struct offload_info *info, +- struct dpif_flow_stats *stats OVS_UNUSED) ++ struct dpif_flow_stats *stats) + { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); + enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev); +@@ -1377,6 +1377,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, + + err = tc_replace_flower(ifindex, prio, handle, &flower, block_id, hook); + if (!err) { ++ if (stats) { ++ memset(stats, 0, sizeof *stats); ++ } + add_ufid_tc_mapping(ufid, flower.prio, flower.handle, netdev, ifindex); + } + +-- +2.14.1 + + diff --git a/Documentation-Fix-security-mailing-list-address.patch b/Documentation-Fix-security-mailing-list-address.patch new file mode 100644 index 0000000..81a332d --- /dev/null +++ b/Documentation-Fix-security-mailing-list-address.patch @@ -0,0 +1,28 @@ +From c11a25f2a105bc81322fa605d947bc53ea9814de Mon Sep 17 00:00:00 2001 +From: Ben Pfaff +Date: Mon, 23 Sep 2019 12:38:56 -0700 +Subject: Documentation: Fix security mailing list address. + +We don't own ovs.org, and I doubt Ojai Valley School would enjoy +receiving our email. + +Reviewed-by: Greg Rose +Signed-off-by: Ben Pfaff +--- + Documentation/internals/mailing-lists.rst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/internals/mailing-lists.rst b/Documentation/internals/mailing-lists.rst +index 33f20277b..e8b344094 100644 +--- a/Documentation/internals/mailing-lists.rst ++++ b/Documentation/internals/mailing-lists.rst +@@ -93,4 +93,4 @@ security + The `security`__ mailing list is for submitting security vulnerabilities to the + security team. + +-__ security@ovs.org ++__ security@openvswitch.org +-- +2.14.1 + + diff --git a/Prepare-for-2.12.1.patch b/Prepare-for-2.12.1.patch new file mode 100644 index 0000000..39b8263 --- /dev/null +++ b/Prepare-for-2.12.1.patch @@ -0,0 +1,55 @@ +From 014a2b02bb5f7e3030a57f6a7bd0e03b4a5823aa Mon Sep 17 00:00:00 2001 +From: Justin Pettit +Date: Tue, 3 Sep 2019 14:57:37 -0700 +Subject: Prepare for 2.12.1. + +Signed-off-by: Justin Pettit +Acked-by: Flavio Leitner +--- + NEWS | 3 +++ + configure.ac | 2 +- + debian/changelog | 6 ++++++ + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/NEWS b/NEWS +index 474d1f3c4..c81890b7e 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,3 +1,6 @@ ++v2.12.1 - xx xxx xxxx ++--------------------- ++ + v2.12.0 - 03 Sep 2019 + --------------------- + - DPDK: +diff --git a/configure.ac b/configure.ac +index 5fee8e9eb..a4322176c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -13,7 +13,7 @@ + # limitations under the License. + + AC_PREREQ(2.63) +-AC_INIT(openvswitch, 2.12.0, bugs@openvswitch.org) ++AC_INIT(openvswitch, 2.12.1, bugs@openvswitch.org) + AC_CONFIG_SRCDIR([datapath/datapath.c]) + AC_CONFIG_MACRO_DIR([m4]) + AC_CONFIG_AUX_DIR([build-aux]) +diff --git a/debian/changelog b/debian/changelog +index b6d0568ef..bb9ea31a0 100644 +--- a/debian/changelog ++++ b/debian/changelog +@@ -1,3 +1,9 @@ ++openvswitch (2.12.1-1) unstable; urgency=low ++ [ Open vSwitch team ] ++ * New upstream version ++ ++ -- Open vSwitch team Tue, 03 Sep 2019 14:57:37 -0700 ++ + openvswitch (2.12.0-1) unstable; urgency=low + [ Open vSwitch team ] + * New upstream version +-- +2.14.1 + + diff --git a/cirrus-Use-FreeBSD-12.1-stable-release.patch b/cirrus-Use-FreeBSD-12.1-stable-release.patch new file mode 100644 index 0000000..df286ab --- /dev/null +++ b/cirrus-Use-FreeBSD-12.1-stable-release.patch @@ -0,0 +1,31 @@ +From 303b3ab0a81270f7bbd258086a8b61e2cefb5dbb Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Fri, 13 Dec 2019 13:52:10 +0100 +Subject: cirrus: Use FreeBSD 12.1 stable release. + +freebsd-12-0-snap image family suddenly removed from the gCloud, +so can not be used anymore. Updating to more recent 12.1 releases. + +Signed-off-by: Ilya Maximets +Acked-by: Ben Pfaff +--- + .cirrus.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.cirrus.yml b/.cirrus.yml +index aaa5e3eeb..48ad3e3c2 100644 +--- a/.cirrus.yml ++++ b/.cirrus.yml +@@ -2,7 +2,7 @@ freebsd_build_task: + + freebsd_instance: + matrix: +- image_family: freebsd-12-0-snap ++ image_family: freebsd-12-1-snap + image_family: freebsd-11-3-snap + cpu: 4 + memory: 8G +-- +2.14.1 + + diff --git a/cirrus-Use-latest-stable-FreeBSD-images.patch b/cirrus-Use-latest-stable-FreeBSD-images.patch new file mode 100644 index 0000000..95bb7f4 --- /dev/null +++ b/cirrus-Use-latest-stable-FreeBSD-images.patch @@ -0,0 +1,43 @@ +From 25a8cb21251d4c45164a03be78d0730590f03ca5 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Tue, 1 Oct 2019 14:28:45 +0300 +Subject: cirrus: Use latest stable FreeBSD images. + +CirrusCI recently introduced [1] new feature to use image families +instead of bare image names for gCloud based instances. +This allows us to use most recent stable builds. All the stable builds +are in the same image family in gCloud and it will run instances using +the most recent one. +This also allows us to simply use 11.3 image instead of 11.2. There +was no such ability previously, because base freebsd-11-3-release-amd64 +image has issues[2] that doesn't allow CirrusCI to use it. However, +later stable 11.3 images from freebsd-11-3-snap family works fine. + +[1] https://github.com/cirruslabs/cirrus-ci-docs/issues/422 +[2] https://github.com/cirruslabs/cirrus-ci-docs/issues/359 + +Signed-off-by: Ilya Maximets +Acked-by: Aaron Conole +--- + .cirrus.yml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/.cirrus.yml b/.cirrus.yml +index eb6af0a71..aaa5e3eeb 100644 +--- a/.cirrus.yml ++++ b/.cirrus.yml +@@ -2,8 +2,8 @@ freebsd_build_task: + + freebsd_instance: + matrix: +- image: freebsd-12-0-release-amd64 +- image: freebsd-11-2-release-amd64 ++ image_family: freebsd-12-0-snap ++ image_family: freebsd-11-3-snap + cpu: 4 + memory: 8G + +-- +2.14.1 + + diff --git a/compat-Add-compat-fix-for-old-kernels.patch b/compat-Add-compat-fix-for-old-kernels.patch new file mode 100644 index 0000000..3733b5b --- /dev/null +++ b/compat-Add-compat-fix-for-old-kernels.patch @@ -0,0 +1,50 @@ +From 3000160ef611af0851014212357e9bfe057dae03 Mon Sep 17 00:00:00 2001 +From: Roi Dayan +Date: Wed, 6 Nov 2019 09:34:46 +0200 +Subject: compat: Add compat fix for old kernels + +In kernels older than 4.8, struct tcf_t didn't have the firstuse. +If openvswitch is compiled with the compat pkt_cls.h then there is +a struct size mismatch between openvswitch and the kernel which cause +parsing netlink actions to fail. +After this commit parsing the netlink actions pass even if compiled with +the compat pkt_cls.h. + +Signed-off-by: Roi Dayan +Signed-off-by: Simon Horman +--- + acinclude.m4 | 2 ++ + include/linux/pkt_cls.h | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/acinclude.m4 b/acinclude.m4 +index fcb45c647..a581e1ef2 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -185,6 +185,8 @@ AC_DEFUN([OVS_CHECK_LINUX_TC], [ + [AC_DEFINE([HAVE_TCA_FLOWER_KEY_ENC_IP_TTL_MASK], [1], + [Define to 1 if TCA_FLOWER_KEY_ENC_IP_TTL_MASK is available.])]) + ++ AC_CHECK_MEMBERS([struct tcf_t.firstuse], [], [], [#include ]) ++ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([#include ], [ + int x = TCA_VLAN_PUSH_VLAN_PRIORITY; +diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h +index 4adea59e7..2f7e328c4 100644 +--- a/include/linux/pkt_cls.h ++++ b/include/linux/pkt_cls.h +@@ -64,7 +64,9 @@ struct tcf_t { + __u64 install; + __u64 lastuse; + __u64 expires; ++#ifdef HAVE_STRUCT_TCF_T_FIRSTUSE + __u64 firstuse; ++#endif + }; + + #define tc_gen \ +-- +2.14.1 + + diff --git a/conntrack-Fix-check_orig_tuple-Valgrind-false-positi.patch b/conntrack-Fix-check_orig_tuple-Valgrind-false-positi.patch new file mode 100644 index 0000000..7980b0a --- /dev/null +++ b/conntrack-Fix-check_orig_tuple-Valgrind-false-positi.patch @@ -0,0 +1,55 @@ +From cc213ea8956059adadf378ca454678f3d2055e04 Mon Sep 17 00:00:00 2001 +From: Darrell Ball +Date: Mon, 23 Sep 2019 16:44:33 -0700 +Subject: conntrack: Fix 'check_orig_tuple()' Valgrind false positive. + +Valgrind reported that 'pkt->md.ct_orig_tuple.ipv4.ipv4_proto' is +uninitialized in 'check_orig_tuple()', if 'ct_state' is zero. Although +this is true, the check is superceded, as even if it succeeds the check +for natted packets based on 'ct_state' is an ORed condition and is intended +to catch this case. +The check is '!(pkt->md.ct_state & (CS_SRC_NAT | CS_DST_NAT))' which +filters out all packets excepted natted ones. Move this check up to +prevent the Valgrind complaint, which also helps performance and also remove +recenlty added redundant check adding extra cycles. + +Fixes: f44733c527da ("conntrack: Validate accessing of conntrack data in pkt_metadata.") +CC: Yifeng Sun +Signed-off-by: Darrell Ball +Signed-off-by: Ben Pfaff +--- + lib/conntrack.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/lib/conntrack.c b/lib/conntrack.c +index 86c16b2fb..0c917543c 100644 +--- a/lib/conntrack.c ++++ b/lib/conntrack.c +@@ -1001,11 +1001,11 @@ check_orig_tuple(struct conntrack *ct, struct dp_packet *pkt, + struct conn **conn, + const struct nat_action_info_t *nat_action_info) + { +- if ((ctx_in->key.dl_type == htons(ETH_TYPE_IP) && ++ if (!(pkt->md.ct_state & (CS_SRC_NAT | CS_DST_NAT)) || ++ (ctx_in->key.dl_type == htons(ETH_TYPE_IP) && + !pkt->md.ct_orig_tuple.ipv4.ipv4_proto) || + (ctx_in->key.dl_type == htons(ETH_TYPE_IPV6) && + !pkt->md.ct_orig_tuple.ipv6.ipv6_proto) || +- !(pkt->md.ct_state & (CS_SRC_NAT | CS_DST_NAT)) || + nat_action_info) { + return false; + } +@@ -1138,8 +1138,7 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, + handle_nat(pkt, conn, zone, ctx->reply, ctx->icmp_related); + } + +- } else if (pkt->md.ct_state +- && check_orig_tuple(ct, pkt, ctx, now, &conn, nat_action_info)) { ++ } else if (check_orig_tuple(ct, pkt, ctx, now, &conn, nat_action_info)) { + create_new_conn = conn_update_state(ct, pkt, ctx, conn, now); + } else { + if (ctx->icmp_related) { +-- +2.14.1 + + diff --git a/conntrack-Fix-reverse_nat_packet-variable-datatype.patch b/conntrack-Fix-reverse_nat_packet-variable-datatype.patch new file mode 100644 index 0000000..ee2fd5f --- /dev/null +++ b/conntrack-Fix-reverse_nat_packet-variable-datatype.patch @@ -0,0 +1,53 @@ +From e6aebc90210baa35d252486d998074e2365a4b26 Mon Sep 17 00:00:00 2001 +From: Darrell Ball +Date: Fri, 30 Aug 2019 09:13:19 -0700 +Subject: conntrack: Fix 'reverse_nat_packet()' variable datatype. + +The datatype 'pad' in the function 'reverse_nat_packet()' was incorrectly +declared as 'char' instead of 'uint8_t'. This can affect reverse natting +of icmpX packets with padding > 127 bytes. At the same time, add some +comments regarding 'extract_l3_ipvX' usage in this function. Found by +inspection. + +Fixes: edd1bef468c0 ("dpdk: Add more ICMP Related NAT support.") +Signed-off-by: Darrell Ball +Signed-off-by: Ben Pfaff +--- + lib/conntrack.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/lib/conntrack.c b/lib/conntrack.c +index 0c917543c..b56ef06ac 100644 +--- a/lib/conntrack.c ++++ b/lib/conntrack.c +@@ -688,7 +688,7 @@ static void + reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn) + { + char *tail = dp_packet_tail(pkt); +- char pad = dp_packet_l2_pad_size(pkt); ++ uint8_t pad = dp_packet_l2_pad_size(pkt); + struct conn_key inner_key; + const char *inner_l4 = NULL; + uint16_t orig_l3_ofs = pkt->l3_ofs; +@@ -698,6 +698,8 @@ reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn) + struct ip_header *nh = dp_packet_l3(pkt); + struct icmp_header *icmp = dp_packet_l4(pkt); + struct ip_header *inner_l3 = (struct ip_header *) (icmp + 1); ++ /* This call is already verified to succeed during the code path from ++ * 'conn_key_extract()' which calls 'extract_l4_icmp()'. */ + extract_l3_ipv4(&inner_key, inner_l3, tail - ((char *)inner_l3) - pad, + &inner_l4, false); + pkt->l3_ofs += (char *) inner_l3 - (char *) nh; +@@ -719,6 +721,8 @@ reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn) + struct icmp6_error_header *icmp6 = dp_packet_l4(pkt); + struct ovs_16aligned_ip6_hdr *inner_l3_6 = + (struct ovs_16aligned_ip6_hdr *) (icmp6 + 1); ++ /* This call is already verified to succeed during the code path from ++ * 'conn_key_extract()' which calls 'extract_l4_icmp6()'. */ + extract_l3_ipv6(&inner_key, inner_l3_6, + tail - ((char *)inner_l3_6) - pad, + &inner_l4); +-- +2.14.1 + + diff --git a/conntrack-Validate-accessing-of-conntrack-data-in-pk.patch b/conntrack-Validate-accessing-of-conntrack-data-in-pk.patch new file mode 100644 index 0000000..34007e6 --- /dev/null +++ b/conntrack-Validate-accessing-of-conntrack-data-in-pk.patch @@ -0,0 +1,102 @@ +From e3b0c19781969c913936904aa2689ceae25f9424 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:36 -0700 +Subject: conntrack: Validate accessing of conntrack data in pkt_metadata + +Valgrind reported: + +1305: ofproto-dpif - conntrack - ipv6 + +==26942== Conditional jump or move depends on uninitialised value(s) +==26942== at 0x587C00: check_orig_tuple (conntrack.c:1006) +==26942== by 0x587C00: process_one (conntrack.c:1141) +==26942== by 0x587C00: conntrack_execute (conntrack.c:1220) +==26942== by 0x47B00F: dp_execute_cb (dpif-netdev.c:7305) +==26942== by 0x4AF756: odp_execute_actions (odp-execute.c:794) +==26942== by 0x477532: dp_netdev_execute_actions (dpif-netdev.c:7349) +==26942== by 0x477532: handle_packet_upcall (dpif-netdev.c:6630) +==26942== by 0x477532: fast_path_processing (dpif-netdev.c:6726) +==26942== by 0x47933C: dp_netdev_input__ (dpif-netdev.c:6814) +==26942== by 0x479AB8: dp_netdev_input (dpif-netdev.c:6852) +==26942== by 0x479AB8: dp_netdev_process_rxq_port (dpif-netdev.c:4287) +==26942== by 0x47A6A9: dpif_netdev_run (dpif-netdev.c:5264) +==26942== by 0x4324E7: type_run (ofproto-dpif.c:342) +==26942== by 0x41C5FE: ofproto_type_run (ofproto.c:1734) +==26942== by 0x40BAAC: bridge_run__ (bridge.c:2965) +==26942== by 0x410CF3: bridge_run (bridge.c:3029) +==26942== by 0x407614: main (ovs-vswitchd.c:127) +==26942== Uninitialised value was created by a heap allocation +==26942== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==26942== by 0x532574: xmalloc (util.c:138) +==26942== by 0x46CD62: dp_packet_new (dp-packet.c:153) +==26942== by 0x4A0431: eth_from_flow_str (netdev-dummy.c:1644) +==26942== by 0x4A0431: netdev_dummy_receive (netdev-dummy.c:1783) +==26942== by 0x531990: process_command (unixctl.c:308) +==26942== by 0x531990: run_connection (unixctl.c:342) +==26942== by 0x531990: unixctl_server_run (unixctl.c:393) +==26942== by 0x40761E: main (ovs-vswitchd.c:128) + +1316: ofproto-dpif - conntrack - tcp port reuse + +==24039== Conditional jump or move depends on uninitialised value(s) +==24039== at 0x587BF5: check_orig_tuple (conntrack.c:1004) +==24039== by 0x587BF5: process_one (conntrack.c:1141) +==24039== by 0x587BF5: conntrack_execute (conntrack.c:1220) +==24039== by 0x47B02F: dp_execute_cb (dpif-netdev.c:7306) +==24039== by 0x4AF7A6: odp_execute_actions (odp-execute.c:794) +==24039== by 0x47755B: dp_netdev_execute_actions (dpif-netdev.c:7350) +==24039== by 0x47755B: handle_packet_upcall (dpif-netdev.c:6631) +==24039== by 0x47755B: fast_path_processing (dpif-netdev.c:6727) +==24039== by 0x47935C: dp_netdev_input__ (dpif-netdev.c:6815) +==24039== by 0x479AD8: dp_netdev_input (dpif-netdev.c:6853) +==24039== by 0x479AD8: dp_netdev_process_rxq_port +(dpif-netdev.c:4287) +==24039== by 0x47A6C9: dpif_netdev_run (dpif-netdev.c:5264) +==24039== by 0x4324F7: type_run (ofproto-dpif.c:342) +==24039== by 0x41C5FE: ofproto_type_run (ofproto.c:1734) +==24039== by 0x40BAAC: bridge_run__ (bridge.c:2965) +==24039== by 0x410CF3: bridge_run (bridge.c:3029) +==24039== by 0x407614: main (ovs-vswitchd.c:127) +==24039== Uninitialised value was created by a heap allocation +==24039== at 0x4C2DB8F: malloc (in +/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==24039== by 0x5325C4: xmalloc (util.c:138) +==24039== by 0x46D144: dp_packet_new (dp-packet.c:153) +==24039== by 0x46D144: dp_packet_new_with_headroom (dp-packet.c:163) +==24039== by 0x51191E: eth_from_hex (packets.c:498) +==24039== by 0x4A03B9: eth_from_packet (netdev-dummy.c:1609) +==24039== by 0x4A03B9: netdev_dummy_receive (netdev-dummy.c:1765) +==24039== by 0x5319E0: process_command (unixctl.c:308) +==24039== by 0x5319E0: run_connection (unixctl.c:342) +==24039== by 0x5319E0: unixctl_server_run (unixctl.c:393) +==24039== by 0x40761E: main (ovs-vswitchd.c:128) + +According to comments in pkt_metadata_init(), conntrack data is valid +only if pkt_metadata.ct_state != 0. This patch prevents +check_orig_tuple() get called when conntrack data is uninitialized. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + lib/conntrack.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/conntrack.c b/lib/conntrack.c +index e5266e579..86c16b2fb 100644 +--- a/lib/conntrack.c ++++ b/lib/conntrack.c +@@ -1138,7 +1138,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, + handle_nat(pkt, conn, zone, ctx->reply, ctx->icmp_related); + } + +- } else if (check_orig_tuple(ct, pkt, ctx, now, &conn, nat_action_info)) { ++ } else if (pkt->md.ct_state ++ && check_orig_tuple(ct, pkt, ctx, now, &conn, nat_action_info)) { + create_new_conn = conn_update_state(ct, pkt, ctx, conn, now); + } else { + if (ctx->icmp_related) { +-- +2.14.1 + + diff --git a/datapath-compat-Backports-bugfixes-for-nf_conncount.patch b/datapath-compat-Backports-bugfixes-for-nf_conncount.patch new file mode 100644 index 0000000..8cb2aad --- /dev/null +++ b/datapath-compat-Backports-bugfixes-for-nf_conncount.patch @@ -0,0 +1,682 @@ +From 74eab93900625f22152b537c0c50a3c925152728 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 7 Aug 2019 15:25:33 -0700 +Subject: datapath: compat: Backports bugfixes for nf_conncount + +This patch backports several critical bug fixes related to +locking and data consistency in nf_conncount code. + +This backport is based on the following upstream net-next upstream commits. +a007232 ("netfilter: nf_conncount: fix argument order to find_next_bit") +c80f10b ("netfilter: nf_conncount: speculative garbage collection on empty lists") +2f971a8 ("netfilter: nf_conncount: move all list iterations under spinlock") +df4a902 ("netfilter: nf_conncount: merge lookup and add functions") +e8cfb37 ("netfilter: nf_conncount: restart search when nodes have been erased") +f7fcc98 ("netfilter: nf_conncount: split gc in two phases") +4cd273b ("netfilter: nf_conncount: don't skip eviction when age is negative") +c78e781 ("netfilter: nf_conncount: replace CONNCOUNT_LOCK_SLOTS with CONNCOUNT_SLOTS") +d4e7df1 ("netfilter: nf_conncount: use rb_link_node_rcu() instead of rb_link_node()") +53ca0f2 ("netfilter: nf_conncount: remove wrong condition check routine") +3c5cdb1 ("netfilter: nf_conncount: fix unexpected permanent node of list.") +31568ec ("netfilter: nf_conncount: fix list_del corruption in conn_free") +fd3e71a ("netfilter: nf_conncount: use spin_lock_bh instead of spin_lock") + +This patch adds additional compat code so that it can build on +all supported kernel versions. + +In addition, this patch helps OVS datapath to always choose bug-fixed +nf_conncount code. If kernel already has these fixes, then kernel's +nf_conncount is being used. Otherwise, OVS falls back to use compat +nf_conncount functions. + +Travis tests are at +https://travis-ci.org/yifsun/ovs-travis/builds/569056850 +On latest RHEL kernel, 'make check-kmod' runs good. + +VMware-BZ: #2396471 + +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + acinclude.m4 | 6 +- + datapath/linux/Modules.mk | 3 +- + datapath/linux/compat/include/linux/rbtree.h | 19 ++ + .../include/net/netfilter/nf_conntrack_count.h | 7 - + datapath/linux/compat/nf_conncount.c | 290 ++++++++++----------- + 5 files changed, 161 insertions(+), 164 deletions(-) + create mode 100644 datapath/linux/compat/include/linux/rbtree.h + +diff --git a/acinclude.m4 b/acinclude.m4 +index 9e1569b07..fcb45c647 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -706,7 +706,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ + OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_nat.h], [nf_nat_range2]) + 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_count.h], ++ [int nf_conncount_add], ++ [], [OVS_DEFINE([HAVE_UPSTREAM_NF_CONNCOUNT])])]) + + OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32]) + OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32_max]) +@@ -1005,6 +1007,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ + [OVS_DEFINE([HAVE_GRE_CALC_HLEN])]) + OVS_GREP_IFELSE([$KSRC/include/net/gre.h], [ip_gre_calc_hlen], + [OVS_DEFINE([HAVE_IP_GRE_CALC_HLEN])]) ++ OVS_GREP_IFELSE([$KSRC/include/linux/rbtree.h], [rb_link_node_rcu], ++ [OVS_DEFINE([HAVE_RBTREE_RB_LINK_NODE_RCU])]) + + if cmp -s datapath/linux/kcompat.h.new \ + datapath/linux/kcompat.h >/dev/null 2>&1; then +diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk +index cbb29f1c6..69d7faeac 100644 +--- a/datapath/linux/Modules.mk ++++ b/datapath/linux/Modules.mk +@@ -116,5 +116,6 @@ openvswitch_headers += \ + linux/compat/include/uapi/linux/netfilter.h \ + linux/compat/include/linux/mm.h \ + linux/compat/include/linux/netfilter.h \ +- linux/compat/include/linux/overflow.h ++ linux/compat/include/linux/overflow.h \ ++ linux/compat/include/linux/rbtree.h + EXTRA_DIST += linux/compat/build-aux/export-check-whitelist +diff --git a/datapath/linux/compat/include/linux/rbtree.h b/datapath/linux/compat/include/linux/rbtree.h +new file mode 100644 +index 000000000..dbf20ff0e +--- /dev/null ++++ b/datapath/linux/compat/include/linux/rbtree.h +@@ -0,0 +1,19 @@ ++#ifndef __LINUX_RBTREE_WRAPPER_H ++#define __LINUX_RBTREE_WRAPPER_H 1 ++ ++#include_next ++ ++#ifndef HAVE_RBTREE_RB_LINK_NODE_RCU ++#include ++ ++static inline void rb_link_node_rcu(struct rb_node *node, struct rb_node *parent, ++ struct rb_node **rb_link) ++{ ++ node->__rb_parent_color = (unsigned long)parent; ++ node->rb_left = node->rb_right = NULL; ++ ++ rcu_assign_pointer(*rb_link, node); ++} ++#endif ++ ++#endif /* __LINUX_RBTREE_WRAPPER_H */ +diff --git a/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h b/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h +index 614017309..2143136aa 100644 +--- a/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h ++++ b/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h +@@ -21,17 +21,10 @@ static inline void rpl_nf_conncount_modexit(void) + #define CONFIG_NETFILTER_CONNCOUNT 1 + struct nf_conncount_data; + +-enum nf_conncount_list_add { +- NF_CONNCOUNT_ADDED, /* list add was ok */ +- NF_CONNCOUNT_ERR, /* -ENOMEM, must drop skb */ +- NF_CONNCOUNT_SKIP, /* list is already reclaimed by gc */ +-}; +- + struct nf_conncount_list { + spinlock_t list_lock; + struct list_head head; /* connections with the same filtering key */ + unsigned int count; /* length of list */ +- bool dead; + }; + + struct nf_conncount_data +diff --git a/datapath/linux/compat/nf_conncount.c b/datapath/linux/compat/nf_conncount.c +index eeae440f8..97bdfb933 100644 +--- a/datapath/linux/compat/nf_conncount.c ++++ b/datapath/linux/compat/nf_conncount.c +@@ -38,12 +38,6 @@ + + #define CONNCOUNT_SLOTS 256U + +-#ifdef CONFIG_LOCKDEP +-#define CONNCOUNT_LOCK_SLOTS 8U +-#else +-#define CONNCOUNT_LOCK_SLOTS 256U +-#endif +- + #define CONNCOUNT_GC_MAX_NODES 8 + #define MAX_KEYLEN 5 + +@@ -54,7 +48,6 @@ struct nf_conncount_tuple { + struct nf_conntrack_zone zone; + int cpu; + u32 jiffies32; +- struct rcu_head rcu_head; + }; + + struct nf_conncount_rb { +@@ -64,7 +57,7 @@ struct nf_conncount_rb { + struct rcu_head rcu_head; + }; + +-static spinlock_t nf_conncount_locks[CONNCOUNT_LOCK_SLOTS] __cacheline_aligned_in_smp; ++static spinlock_t nf_conncount_locks[CONNCOUNT_SLOTS] __cacheline_aligned_in_smp; + + struct nf_conncount_data { + unsigned int keylen; +@@ -93,74 +86,25 @@ static int key_diff(const u32 *a, const u32 *b, unsigned int klen) + return memcmp(a, b, klen * sizeof(u32)); + } + +-static enum nf_conncount_list_add +-nf_conncount_add(struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) +-{ +- struct nf_conncount_tuple *conn; +- +- if (WARN_ON_ONCE(list->count > INT_MAX)) +- return NF_CONNCOUNT_ERR; +- +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) +- return NF_CONNCOUNT_ERR; +- +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- spin_lock(&list->list_lock); +- if (list->dead == true) { +- kmem_cache_free(conncount_conn_cachep, conn); +- spin_unlock(&list->list_lock); +- return NF_CONNCOUNT_SKIP; +- } +- list_add_tail(&conn->node, &list->head); +- list->count++; +- spin_unlock(&list->list_lock); +- return NF_CONNCOUNT_ADDED; +-} +- +-static void __conn_free(struct rcu_head *h) +-{ +- struct nf_conncount_tuple *conn; +- +- conn = container_of(h, struct nf_conncount_tuple, rcu_head); +- kmem_cache_free(conncount_conn_cachep, conn); +-} +- +-static bool conn_free(struct nf_conncount_list *list, ++static void conn_free(struct nf_conncount_list *list, + struct nf_conncount_tuple *conn) + { +- bool free_entry = false; +- +- spin_lock(&list->list_lock); +- +- if (list->count == 0) { +- spin_unlock(&list->list_lock); +- return free_entry; +- } ++ lockdep_assert_held(&list->list_lock); + + list->count--; +- list_del_rcu(&conn->node); +- if (list->count == 0) +- free_entry = true; ++ list_del(&conn->node); + +- spin_unlock(&list->list_lock); +- call_rcu(&conn->rcu_head, __conn_free); +- return free_entry; ++ kmem_cache_free(conncount_conn_cachep, conn); + } + + static const struct nf_conntrack_tuple_hash * + find_or_evict(struct net *net, struct nf_conncount_list *list, +- struct nf_conncount_tuple *conn, bool *free_entry) ++ struct nf_conncount_tuple *conn) + { + const struct nf_conntrack_tuple_hash *found; + unsigned long a, b; + int cpu = raw_smp_processor_id(); +- __s32 age; ++ u32 age; + + found = nf_conntrack_find_get(net, &conn->zone, &conn->tuple); + if (found) +@@ -175,52 +119,45 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + */ + age = a - b; + if (conn->cpu == cpu || age >= 2) { +- *free_entry = conn_free(list, conn); ++ conn_free(list, conn); + return ERR_PTR(-ENOENT); + } + + return ERR_PTR(-EAGAIN); + } + +-static void nf_conncount_lookup(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone, +- bool *addit) ++static int __nf_conncount_add(struct net *net, ++ struct nf_conncount_list *list, ++ const struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone *zone) + { + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; + struct nf_conn *found_ct; + unsigned int collect = 0; +- bool free_entry = false; +- +- /* best effort only */ +- *addit = tuple ? true : false; + + /* check the saved connections */ + list_for_each_entry_safe(conn, conn_n, &list->head, node) { + if (collect > CONNCOUNT_GC_MAX_NODES) + break; + +- found = find_or_evict(net, list, conn, &free_entry); ++ found = find_or_evict(net, list, conn); + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (!tuple) +- continue; +- + if (nf_ct_tuple_equal(&conn->tuple, tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- *addit = false; +- } else if (PTR_ERR(found) == -ENOENT) ++ return 0; /* already exists */ ++ } else { + collect++; ++ } + continue; + } + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (tuple && nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -228,7 +165,8 @@ static void nf_conncount_lookup(struct net *net, + * + * Attempt to avoid a re-add in this case. + */ +- *addit = false; ++ nf_ct_put(found_ct); ++ return 0; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -242,34 +180,64 @@ static void nf_conncount_lookup(struct net *net, + + nf_ct_put(found_ct); + } ++ ++ if (WARN_ON_ONCE(list->count > INT_MAX)) ++ return -EOVERFLOW; ++ ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) ++ return -ENOMEM; ++ ++ conn->tuple = *tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ list_add_tail(&conn->node, &list->head); ++ list->count++; ++ return 0; ++} ++ ++int nf_conncount_add(struct net *net, ++ struct nf_conncount_list *list, ++ const struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone *zone) ++{ ++ int ret; ++ ++ /* check the saved connections */ ++ spin_lock_bh(&list->list_lock); ++ ret = __nf_conncount_add(net, list, tuple, zone); ++ spin_unlock_bh(&list->list_lock); ++ ++ return ret; + } + + static void nf_conncount_list_init(struct nf_conncount_list *list) + { + spin_lock_init(&list->list_lock); + INIT_LIST_HEAD(&list->head); +- list->count = 1; +- list->dead = false; ++ list->count = 0; + } + +-/* Return true if the list is empty */ ++/* Return true if the list is empty. Must be called with BH disabled. */ + static bool nf_conncount_gc_list(struct net *net, +- struct nf_conncount_list *list) ++ struct nf_conncount_list *list) + { + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; + struct nf_conn *found_ct; + unsigned int collected = 0; +- bool free_entry = false; ++ bool ret = false; ++ ++ /* don't bother if other cpu is already doing GC */ ++ if (!spin_trylock(&list->list_lock)) ++ return false; + + list_for_each_entry_safe(conn, conn_n, &list->head, node) { +- found = find_or_evict(net, list, conn, &free_entry); ++ found = find_or_evict(net, list, conn); + if (IS_ERR(found)) { +- if (PTR_ERR(found) == -ENOENT) { +- if (free_entry) +- return true; ++ if (PTR_ERR(found) == -ENOENT) + collected++; +- } + continue; + } + +@@ -280,17 +248,21 @@ static bool nf_conncount_gc_list(struct net *net, + * closed already -> ditch it + */ + nf_ct_put(found_ct); +- if (conn_free(list, conn)) +- return true; ++ conn_free(list, conn); + collected++; + continue; + } + + nf_ct_put(found_ct); + if (collected > CONNCOUNT_GC_MAX_NODES) +- return false; ++ break; + } +- return false; ++ ++ if (!list->count) ++ ret = true; ++ spin_unlock(&list->list_lock); ++ ++ return ret; + } + + static void __tree_nodes_free(struct rcu_head *h) +@@ -301,6 +273,7 @@ static void __tree_nodes_free(struct rcu_head *h) + kmem_cache_free(conncount_rb_cachep, rbconn); + } + ++/* caller must hold tree nf_conncount_locks[] lock */ + static void tree_nodes_free(struct rb_root *root, + struct nf_conncount_rb *gc_nodes[], + unsigned int gc_count) +@@ -310,8 +283,7 @@ static void tree_nodes_free(struct rb_root *root, + while (gc_count) { + rbconn = gc_nodes[--gc_count]; + spin_lock(&rbconn->list.list_lock); +- if (rbconn->list.count == 0 && rbconn->list.dead == false) { +- rbconn->list.dead = true; ++ if (!rbconn->list.count) { + rb_erase(&rbconn->node, root); + call_rcu(&rbconn->rcu_head, __tree_nodes_free); + } +@@ -331,20 +303,19 @@ insert_tree(struct net *net, + struct rb_root *root, + unsigned int hash, + const u32 *key, +- u8 keylen, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone) + { +- enum nf_conncount_list_add ret; + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; + struct rb_node **rbnode, *parent; + struct nf_conncount_rb *rbconn; + struct nf_conncount_tuple *conn; + unsigned int count = 0, gc_count = 0; +- bool node_found = false; +- +- spin_lock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]); ++ u8 keylen = data->keylen; ++ bool do_gc = true; + ++ spin_lock_bh(&nf_conncount_locks[hash]); ++restart: + parent = NULL; + rbnode = &(root->rb_node); + while (*rbnode) { +@@ -358,45 +329,32 @@ insert_tree(struct net *net, + } else if (diff > 0) { + rbnode = &((*rbnode)->rb_right); + } else { +- /* unlikely: other cpu added node already */ +- node_found = true; +- ret = nf_conncount_add(&rbconn->list, tuple, zone); +- if (ret == NF_CONNCOUNT_ERR) { ++ int ret; ++ ++ ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ if (ret) + count = 0; /* hotdrop */ +- } else if (ret == NF_CONNCOUNT_ADDED) { ++ else + count = rbconn->list.count; +- } else { +- /* NF_CONNCOUNT_SKIP, rbconn is already +- * reclaimed by gc, insert a new tree node +- */ +- node_found = false; +- } +- break; ++ tree_nodes_free(root, gc_nodes, gc_count); ++ goto out_unlock; + } + + if (gc_count >= ARRAY_SIZE(gc_nodes)) + continue; + +- if (nf_conncount_gc_list(net, &rbconn->list)) ++ if (do_gc && nf_conncount_gc_list(net, &rbconn->list)) + gc_nodes[gc_count++] = rbconn; + } + + if (gc_count) { + tree_nodes_free(root, gc_nodes, gc_count); +- /* tree_node_free before new allocation permits +- * allocator to re-use newly free'd object. +- * +- * This is a rare event; in most cases we will find +- * existing node to re-use. (or gc_count is 0). +- */ +- +- if (gc_count >= ARRAY_SIZE(gc_nodes)) +- schedule_gc_worker(data, hash); ++ schedule_gc_worker(data, hash); ++ gc_count = 0; ++ do_gc = false; ++ goto restart; + } + +- if (node_found) +- goto out_unlock; +- + /* expected case: match, insert new node */ + rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); + if (rbconn == NULL) +@@ -415,11 +373,12 @@ insert_tree(struct net *net, + nf_conncount_list_init(&rbconn->list); + list_add(&conn->node, &rbconn->list.head); + count = 1; ++ rbconn->list.count = count; + +- rb_link_node(&rbconn->node, parent, rbnode); ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); + rb_insert_color(&rbconn->node, root); + out_unlock: +- spin_unlock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]); ++ spin_unlock_bh(&nf_conncount_locks[hash]); + return count; + } + +@@ -430,7 +389,6 @@ count_tree(struct net *net, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone) + { +- enum nf_conncount_list_add ret; + struct rb_root *root; + struct rb_node *parent; + struct nf_conncount_rb *rbconn; +@@ -443,7 +401,6 @@ count_tree(struct net *net, + parent = rcu_dereference_raw(root->rb_node); + while (parent) { + int diff; +- bool addit; + + rbconn = rb_entry(parent, struct nf_conncount_rb, node); + +@@ -453,31 +410,36 @@ count_tree(struct net *net, + } else if (diff > 0) { + parent = rcu_dereference_raw(parent->rb_right); + } else { +- /* same source network -> be counted! */ +- nf_conncount_lookup(net, &rbconn->list, tuple, zone, +- &addit); ++ int ret; + +- if (!addit) ++ if (!tuple) { ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + +- ret = nf_conncount_add(&rbconn->list, tuple, zone); +- if (ret == NF_CONNCOUNT_ERR) { +- return 0; /* hotdrop */ +- } else if (ret == NF_CONNCOUNT_ADDED) { +- return rbconn->list.count; +- } else { +- /* NF_CONNCOUNT_SKIP, rbconn is already +- * reclaimed by gc, insert a new tree node +- */ ++ spin_lock_bh(&rbconn->list.list_lock); ++ /* Node might be about to be free'd. ++ * We need to defer to insert_tree() in this case. ++ */ ++ if (rbconn->list.count == 0) { ++ spin_unlock_bh(&rbconn->list.list_lock); + break; + } ++ ++ /* same source network -> be counted! */ ++ ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ spin_unlock_bh(&rbconn->list.list_lock); ++ if (ret) ++ return 0; /* hotdrop */ ++ else ++ return rbconn->list.count; + } + } + + if (!tuple) + return 0; + +- return insert_tree(net, data, root, hash, key, keylen, tuple, zone); ++ return insert_tree(net, data, root, hash, key, tuple, zone); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -488,27 +450,48 @@ static void tree_gc_worker(struct work_struct *work) + struct rb_node *node; + unsigned int tree, next_tree, gc_count = 0; + +- tree = data->gc_tree % CONNCOUNT_LOCK_SLOTS; ++ tree = data->gc_tree % CONNCOUNT_SLOTS; + root = &data->root[tree]; + ++ local_bh_disable(); + rcu_read_lock(); + for (node = rb_first(root); node != NULL; node = rb_next(node)) { + rbconn = rb_entry(node, struct nf_conncount_rb, node); + if (nf_conncount_gc_list(data->net, &rbconn->list)) +- gc_nodes[gc_count++] = rbconn; ++ gc_count++; + } + rcu_read_unlock(); ++ local_bh_enable(); ++ ++ cond_resched(); + + spin_lock_bh(&nf_conncount_locks[tree]); ++ if (gc_count < ARRAY_SIZE(gc_nodes)) ++ goto next; /* do not bother */ + +- if (gc_count) { +- tree_nodes_free(root, gc_nodes, gc_count); ++ gc_count = 0; ++ node = rb_first(root); ++ while (node != NULL) { ++ rbconn = rb_entry(node, struct nf_conncount_rb, node); ++ node = rb_next(node); ++ ++ if (rbconn->list.count > 0) ++ continue; ++ ++ gc_nodes[gc_count++] = rbconn; ++ if (gc_count >= ARRAY_SIZE(gc_nodes)) { ++ tree_nodes_free(root, gc_nodes, gc_count); ++ gc_count = 0; ++ } + } + ++ tree_nodes_free(root, gc_nodes, gc_count); ++next: ++ + clear_bit(tree, data->pending_trees); + + next_tree = (tree + 1) % CONNCOUNT_SLOTS; +- next_tree = find_next_bit(data->pending_trees, next_tree, CONNCOUNT_SLOTS); ++ next_tree = find_next_bit(data->pending_trees, CONNCOUNT_SLOTS, next_tree); + + if (next_tree < CONNCOUNT_SLOTS) { + data->gc_tree = next_tree; +@@ -533,7 +516,7 @@ unsigned int rpl_nf_conncount_count(struct net *net, + EXPORT_SYMBOL_GPL(rpl_nf_conncount_count); + + struct nf_conncount_data *rpl_nf_conncount_init(struct net *net, unsigned int family, +- unsigned int keylen) ++ unsigned int keylen) + { + struct nf_conncount_data *data; + int ret, i; +@@ -609,10 +592,7 @@ int rpl_nf_conncount_modinit(void) + { + int i; + +- BUILD_BUG_ON(CONNCOUNT_LOCK_SLOTS > CONNCOUNT_SLOTS); +- BUILD_BUG_ON((CONNCOUNT_SLOTS % CONNCOUNT_LOCK_SLOTS) != 0); +- +- for (i = 0; i < CONNCOUNT_LOCK_SLOTS; ++i) ++ for (i = 0; i < CONNCOUNT_SLOTS; ++i) + spin_lock_init(&nf_conncount_locks[i]); + + conncount_conn_cachep = kmem_cache_create("nf_conncount_tuple", +-- +2.14.1 + + diff --git a/db-ctl-base-Free-leaked-ovsdb_datum.patch b/db-ctl-base-Free-leaked-ovsdb_datum.patch new file mode 100644 index 0000000..f60d91f --- /dev/null +++ b/db-ctl-base-Free-leaked-ovsdb_datum.patch @@ -0,0 +1,81 @@ +From f4e6978ca49266448190e8e5bac68a8539795eb7 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:35 -0700 +Subject: db-ctl-base: Free leaked ovsdb_datum + +Valgrind reported: + +2491: database commands -- negative checks + +==19245== 36 (32 direct, 4 indirect) bytes in 1 blocks are definitely lost in loss record 36 of 53 +==19245== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==19245== by 0x431AB4: xrealloc (util.c:149) +==19245== by 0x41656D: ovsdb_datum_reallocate (ovsdb-data.c:1883) +==19245== by 0x41656D: ovsdb_datum_union (ovsdb-data.c:1961) +==19245== by 0x4107B2: cmd_add (db-ctl-base.c:1494) +==19245== by 0x406E2E: do_vsctl (ovs-vsctl.c:2626) +==19245== by 0x406E2E: main (ovs-vsctl.c:183) + +==19252== 16 bytes in 1 blocks are definitely lost in loss record 9 of 52 +==19252== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==19252== by 0x430F74: xmalloc (util.c:138) +==19252== by 0x414D07: clone_atoms (ovsdb-data.c:990) +==19252== by 0x4153F6: ovsdb_datum_clone (ovsdb-data.c:1012) +==19252== by 0x4104D3: cmd_remove (db-ctl-base.c:1564) +==19252== by 0x406E2E: do_vsctl (ovs-vsctl.c:2626) +==19252== by 0x406E2E: main (ovs-vsctl.c:183) + +This patch fixes them. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + lib/db-ctl-base.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/lib/db-ctl-base.c b/lib/db-ctl-base.c +index 3bd9f006a..6878d6326 100644 +--- a/lib/db-ctl-base.c ++++ b/lib/db-ctl-base.c +@@ -1489,6 +1489,7 @@ cmd_add(struct ctl_context *ctx) + ctx->error = ovsdb_datum_from_string(&add, &add_type, ctx->argv[i], + ctx->symtab); + if (ctx->error) { ++ ovsdb_datum_destroy(&old, &column->type); + return; + } + ovsdb_datum_union(&old, &add, type, false); +@@ -1500,6 +1501,7 @@ cmd_add(struct ctl_context *ctx) + old.n, + type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs", + column->name, table->name, type->n_max); ++ ovsdb_datum_destroy(&old, &column->type); + return; + } + ovsdb_idl_txn_verify(row, column); +@@ -1581,10 +1583,12 @@ cmd_remove(struct ctl_context *ctx) + ctx->argv[i], + ctx->symtab); + if (ctx->error) { ++ ovsdb_datum_destroy(&old, &column->type); + return; + } + } else { + ctx->error = error; ++ ovsdb_datum_destroy(&old, &column->type); + return; + } + } +@@ -1596,6 +1600,7 @@ cmd_remove(struct ctl_context *ctx) + "table %s but the minimum number is %u", old.n, + type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs", + column->name, table->name, type->n_min); ++ ovsdb_datum_destroy(&old, &column->type); + return; + } + ovsdb_idl_txn_verify(row, column); +-- +2.14.1 + + diff --git a/dns-resolve-Free-struct-ub_result-when-callback-retu.patch b/dns-resolve-Free-struct-ub_result-when-callback-retu.patch new file mode 100644 index 0000000..ed5e2da --- /dev/null +++ b/dns-resolve-Free-struct-ub_result-when-callback-retu.patch @@ -0,0 +1,69 @@ +From 2f4232d58d414f1e0e5cfe82ce4f7ff7fc5de621 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:33 -0700 +Subject: dns-resolve: Free 'struct ub_result' when callback returns error results + +Valgrind reported: + +1074: ofproto - flush flows, groups, and meters for controller change + +==5499== 695 (288 direct, 407 indirect) bytes in 3 blocks are definitely lost in loss record 344 of 355 +==5499== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==5499== by 0x5E7F145: ??? (in /usr/lib/x86_64-linux-gnu/libunbound.so.2.4.0) +==5499== by 0x5E6EBDE: ub_resolve_async (in /usr/lib/x86_64-linux-gnu/libunbound.so.2.4.0) +==5499== by 0x55C739: resolve_async__.part.5 (dns-resolve.c:233) +==5499== by 0x55C85C: resolve_async__ (dns-resolve.c:261) +==5499== by 0x55C85C: resolve_callback__ (dns-resolve.c:262) +==5499== by 0x5E6FEF1: ub_process (in /usr/lib/x86_64-linux-gnu/libunbound.so.2.4.0) +==5499== by 0x55CAF3: dns_resolve (dns-resolve.c:153) +==5499== by 0x523864: parse_sockaddr_components_dns (socket-util.c:438) +==5499== by 0x523864: parse_sockaddr_components (socket-util.c:504) +==5499== by 0x524468: inet_parse_active (socket-util.c:541) +==5499== by 0x524564: inet_open_active (socket-util.c:579) +==5499== by 0x5959F9: tcp_open (stream-tcp.c:56) +==5499== by 0x529192: stream_open (stream.c:228) +==5499== by 0x529910: stream_open_with_default_port (stream.c:724) +==5499== by 0x595FAE: vconn_stream_open (vconn-stream.c:81) +==5499== by 0x535C9B: vconn_open (vconn.c:250) +==5499== by 0x517C59: reconnect (rconn.c:467) +==5499== by 0x5184C7: run_BACKOFF (rconn.c:492) +==5499== by 0x5184C7: rconn_run (rconn.c:660) +==5499== by 0x457FE8: ofservice_run (connmgr.c:1992) +==5499== by 0x457FE8: connmgr_run (connmgr.c:367) +==5499== by 0x41E0F5: ofproto_run (ofproto.c:1845) +==5499== by 0x40BA63: bridge_run__ (bridge.c:2971) + +In ub_resolve_async's callback function, 'struct ub_result' should be +finally freed even if there is a resolving error. This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + lib/dns-resolve.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/dns-resolve.c b/lib/dns-resolve.c +index e98e65f49..1ff58960f 100644 +--- a/lib/dns-resolve.c ++++ b/lib/dns-resolve.c +@@ -251,6 +251,7 @@ resolve_callback__(void *req_, int err, struct ub_result *result) + struct resolve_request *req = req_; + + if (err != 0 || (result->qtype == ns_t_aaaa && !result->havedata)) { ++ ub_resolve_free(result); + req->state = RESOLVE_ERROR; + VLOG_ERR_RL(&rl, "%s: failed to resolve", req->name); + return; +@@ -265,6 +266,7 @@ resolve_callback__(void *req_, int err, struct ub_result *result) + + char *addr; + if (!resolve_result_to_addr__(result, &addr)) { ++ ub_resolve_free(result); + req->state = RESOLVE_ERROR; + VLOG_ERR_RL(&rl, "%s: failed to resolve", req->name); + return; +-- +2.14.1 + + diff --git a/doc-Fix-incorrect-reference-for-dpdk-testpmd.patch b/doc-Fix-incorrect-reference-for-dpdk-testpmd.patch new file mode 100644 index 0000000..d6272c2 --- /dev/null +++ b/doc-Fix-incorrect-reference-for-dpdk-testpmd.patch @@ -0,0 +1,44 @@ +From 093fd99a4c12d902110ac15cd583c37ee6f2ea12 Mon Sep 17 00:00:00 2001 +From: David Marchand +Date: Thu, 3 Oct 2019 20:45:20 +0200 +Subject: doc: Fix incorrect reference for dpdk-testpmd. + +Move back the dpdk-testpmd reference to the right section of this +document so that the link in howto/dpdk does not point to +"vhost-user-client tx retries config". + +Fixes: 080f080c3bc1 ("netdev-dpdk: Enable tx-retries-max config.") + +Signed-off-by: David Marchand +Acked-by: Kevin Traynor +Signed-off-by: Ilya Maximets +--- + Documentation/topics/dpdk/vhost-user.rst | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Documentation/topics/dpdk/vhost-user.rst b/Documentation/topics/dpdk/vhost-user.rst +index 724aa62f6..fab87bd3d 100644 +--- a/Documentation/topics/dpdk/vhost-user.rst ++++ b/Documentation/topics/dpdk/vhost-user.rst +@@ -348,8 +348,6 @@ The default value is ``false``. + across a 10Gbps link possibly unacceptably slow. So recommended hugepage + size is 2MB. + +-.. _dpdk-testpmd: +- + vhost-user-client tx retries config + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +@@ -375,6 +373,8 @@ Tx retries max can be set for vhost-user-client ports:: + + Configurable vhost tx retries are not supported with vhost-user ports. + ++.. _dpdk-testpmd: ++ + DPDK in the Guest + ----------------- + +-- +2.14.1 + + diff --git a/dp-packet-Fix-clearing-copying-of-memory-layout-flag.patch b/dp-packet-Fix-clearing-copying-of-memory-layout-flag.patch new file mode 100644 index 0000000..d2e0c93 --- /dev/null +++ b/dp-packet-Fix-clearing-copying-of-memory-layout-flag.patch @@ -0,0 +1,69 @@ +From 8c3af9f8819bc4ec17134708a6611dd513278d1f Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Thu, 21 Nov 2019 14:14:52 +0100 +Subject: dp-packet: Fix clearing/copying of memory layout flags. + +'ol_flags' of DPDK mbuf could contain bits responsible for external +or indirect buffers which are not actually offload flags in a common +sense. Clearing/copying of these flags could lead to memory leaks of +external memory chunks and crashes due to access to wrong memory. + +OVS should not clear these flags while resetting offloads and also +should not copy them to the newly allocated packets. + +This change is required to support DPDK 19.11, as some drivers may +return mbufs with these flags set. However, it might be good to do +the same for DPDK 18.11, because these flags are present and should +be taken into account. + +Fixes: 03f3f9c0faf8 ("dpdk: Update to use DPDK 18.11.") +Signed-off-by: Ilya Maximets +Reviewed-by: David Marchand +Acked-by: Ben Pfaff +Acked-by: Kevin Traynor +--- + lib/dp-packet.c | 1 + + lib/dp-packet.h | 7 ++++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/lib/dp-packet.c b/lib/dp-packet.c +index 62d7faa4c..8dfedcb7c 100644 +--- a/lib/dp-packet.c ++++ b/lib/dp-packet.c +@@ -194,6 +194,7 @@ dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom) + + #ifdef DPDK_NETDEV + new_buffer->mbuf.ol_flags = buffer->mbuf.ol_flags; ++ new_buffer->mbuf.ol_flags &= ~DPDK_MBUF_NON_OFFLOADING_FLAGS; + #endif + + if (dp_packet_rss_valid(buffer)) { +diff --git a/lib/dp-packet.h b/lib/dp-packet.h +index 14f0897fa..3dd59e25d 100644 +--- a/lib/dp-packet.h ++++ b/lib/dp-packet.h +@@ -54,6 +54,11 @@ enum dp_packet_offload_mask { + DP_PACKET_OL_RSS_HASH_MASK = 0x1, /* Is the 'rss_hash' valid? */ + DP_PACKET_OL_FLOW_MARK_MASK = 0x2, /* Is the 'flow_mark' valid? */ + }; ++#else ++/* DPDK mbuf ol_flags that are not really an offload flags. These are mostly ++ * related to mbuf memory layout and OVS should not touch/clear them. */ ++#define DPDK_MBUF_NON_OFFLOADING_FLAGS (EXT_ATTACHED_MBUF | \ ++ IND_ATTACHED_MBUF) + #endif + + /* Buffer for holding packet data. A dp_packet is automatically reallocated +@@ -538,7 +543,7 @@ dp_packet_rss_valid(const struct dp_packet *p) + static inline void + dp_packet_reset_offload(struct dp_packet *p) + { +- p->mbuf.ol_flags = 0; ++ p->mbuf.ol_flags &= DPDK_MBUF_NON_OFFLOADING_FLAGS; + } + + static inline bool +-- +2.14.1 + + diff --git a/dpdk-Use-DPDK-18.11.5-release.patch b/dpdk-Use-DPDK-18.11.5-release.patch new file mode 100644 index 0000000..f39cb7d --- /dev/null +++ b/dpdk-Use-DPDK-18.11.5-release.patch @@ -0,0 +1,107 @@ +From a835ee279bf88650c0eba0442f08bbc86620aac3 Mon Sep 17 00:00:00 2001 +From: Ian Stokes +Date: Tue, 26 Nov 2019 12:03:29 +0000 +Subject: dpdk: Use DPDK 18.11.5 release. + +Modify travis linux build script to use the latest DPDK stable release +18.11.5. Update docs for latest DPDK stable releases. + +Signed-off-by: Ian Stokes +Acked-by: Ilya Maximets +Acked-by: Kevin Traynor +--- + .travis/linux-build.sh | 2 +- + Documentation/faq/releases.rst | 4 ++-- + Documentation/intro/install/dpdk.rst | 8 ++++---- + Documentation/topics/dpdk/vhost-user.rst | 6 +++--- + NEWS | 3 +++ + 5 files changed, 13 insertions(+), 10 deletions(-) + +diff --git a/.travis/linux-build.sh b/.travis/linux-build.sh +index 17428fa6b..1afa42914 100755 +--- a/.travis/linux-build.sh ++++ b/.travis/linux-build.sh +@@ -105,7 +105,7 @@ fi + + if [ "$DPDK" ] || [ "$DPDK_SHARED" ]; then + if [ -z "$DPDK_VER" ]; then +- DPDK_VER="18.11.2" ++ DPDK_VER="18.11.5" + fi + install_dpdk $DPDK_VER + if [ "$CC" = "clang" ]; then +diff --git a/Documentation/faq/releases.rst b/Documentation/faq/releases.rst +index e18f5db75..cc06571f5 100644 +--- a/Documentation/faq/releases.rst ++++ b/Documentation/faq/releases.rst +@@ -178,8 +178,8 @@ Q: What DPDK version does each Open vSwitch release work with? + 2.8.x 17.05.2 + 2.9.x 17.11.4 + 2.10.x 17.11.4 +- 2.11.x 18.11.2 +- 2.12.x 18.11.2 ++ 2.11.x 18.11.5 ++ 2.12.x 18.11.5 + ============ ======= + + Q: Are all the DPDK releases that OVS versions work with maintained? +diff --git a/Documentation/intro/install/dpdk.rst b/Documentation/intro/install/dpdk.rst +index 6e5f1ea60..13aa8a16f 100644 +--- a/Documentation/intro/install/dpdk.rst ++++ b/Documentation/intro/install/dpdk.rst +@@ -42,7 +42,7 @@ Build requirements + In addition to the requirements described in :doc:`general`, building Open + vSwitch with DPDK will require the following: + +-- DPDK 18.11.2 ++- DPDK 18.11.5 + + - A `DPDK supported NIC`_ + +@@ -71,9 +71,9 @@ Install DPDK + #. Download the `DPDK sources`_, extract the file and set ``DPDK_DIR``:: + + $ cd /usr/src/ +- $ wget http://fast.dpdk.org/rel/dpdk-18.11.2.tar.xz +- $ tar xf dpdk-18.11.2.tar.xz +- $ export DPDK_DIR=/usr/src/dpdk-stable-18.11.2 ++ $ wget http://fast.dpdk.org/rel/dpdk-18.11.5.tar.xz ++ $ tar xf dpdk-18.11.5.tar.xz ++ $ export DPDK_DIR=/usr/src/dpdk-stable-18.11.5 + $ cd $DPDK_DIR + + #. (Optional) Configure DPDK as a shared library +diff --git a/Documentation/topics/dpdk/vhost-user.rst b/Documentation/topics/dpdk/vhost-user.rst +index fab87bd3d..a0d35cdd4 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 + DPDK sources to VM and build DPDK:: + + $ cd /root/dpdk/ +- $ wget http://fast.dpdk.org/rel/dpdk-18.11.2.tar.xz +- $ tar xf dpdk-18.11.2.tar.xz +- $ export DPDK_DIR=/root/dpdk/dpdk-stable-18.11.2 ++ $ wget http://fast.dpdk.org/rel/dpdk-18.11.5.tar.xz ++ $ tar xf dpdk-18.11.5.tar.xz ++ $ export DPDK_DIR=/root/dpdk/dpdk-stable-18.11.5 + $ export DPDK_TARGET=x86_64-native-linuxapp-gcc + $ export DPDK_BUILD=$DPDK_DIR/$DPDK_TARGET + $ cd $DPDK_DIR +diff --git a/NEWS b/NEWS +index c81890b7e..b9be7f7ce 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,5 +1,8 @@ + v2.12.1 - xx xxx xxxx + --------------------- ++ - DPDK: ++ * OVS validated with DPDK 18.11.5, due to the inclusion of a fix for ++ CVE-2019-14818, this DPDK version is strongly recommended to be used. + + v2.12.0 - 03 Sep 2019 + --------------------- +-- +2.14.1 + + diff --git a/dpif-netdev-Avoid-infinite-re-addition-of-misconfigu.patch b/dpif-netdev-Avoid-infinite-re-addition-of-misconfigu.patch new file mode 100644 index 0000000..59571ba --- /dev/null +++ b/dpif-netdev-Avoid-infinite-re-addition-of-misconfigu.patch @@ -0,0 +1,112 @@ +From 002cb62160cba242d49f918fd49aa54f957413b1 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Sat, 7 Dec 2019 15:46:16 +0100 +Subject: dpif-netdev: Avoid infinite re-addition of misconfigured ports. + +Infinite re-addition of failed ports happens if the device in userspace +datapath has a linux network interface and it's not able to be +configured. For example, if the first reconfiguration fails because of +misconfiguration or bad initial device state. +In current code victims are afxdp ports and the Mellanox NIC ports +opened by the DPDK due to their bifurcated drivers (It's unlikely for +usual netdev-linux ports to fail). + +The root cause: Every change in the state of the network interface +of a linux kernel device generates if-notifier event and if-notifier +event triggers the OVS code to re-apply the configuration of ports, +i.e. add broken ports back. The most obvious part is that dpif-netdev +changes the device flags before trying to configure it: + + 1. add_port() + 2. set_flags() --> if-notifier event + 3. reconfigure() --> port removal from the datapath due to + misconfiguration or any other issue in + the underlying device. + 4. setting flags back --> another if-notifier event. + 5. There was new if-notifier event? + yes --> re-apply all settings. --> goto step 1. + +Easy way to reproduce is to add afxdp port with n_rxq=N, where N is +bigger than device supports. + +This patch fixes the most obvious case for this issue by moving +enabling of a promisc mode later to the place where we already know +that device could be added to datapath without errors, i.e. after +its first successful reconfiguration. + +Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2019-September/363038.html +Signed-off-by: Ilya Maximets +Acked-by: William Tu +--- + lib/dpif-netdev.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c +index 370840fa0..1f405b7d2 100644 +--- a/lib/dpif-netdev.c ++++ b/lib/dpif-netdev.c +@@ -1793,7 +1793,6 @@ static int + port_create(const char *devname, const char *type, + odp_port_t port_no, struct dp_netdev_port **portp) + { +- struct netdev_saved_flags *sf; + struct dp_netdev_port *port; + enum netdev_flags flags; + struct netdev *netdev; +@@ -1815,17 +1814,11 @@ port_create(const char *devname, const char *type, + goto out; + } + +- error = netdev_turn_flags_on(netdev, NETDEV_PROMISC, &sf); +- if (error) { +- VLOG_ERR("%s: cannot set promisc flag", devname); +- goto out; +- } +- + port = xzalloc(sizeof *port); + port->port_no = port_no; + port->netdev = netdev; + port->type = xstrdup(type); +- port->sf = sf; ++ port->sf = NULL; + port->emc_enabled = true; + port->need_reconfigure = true; + ovs_mutex_init(&port->txq_used_mutex); +@@ -1844,6 +1837,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type, + odp_port_t port_no) + OVS_REQUIRES(dp->port_mutex) + { ++ struct netdev_saved_flags *sf; + struct dp_netdev_port *port; + int error; + +@@ -1863,7 +1857,24 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type, + reconfigure_datapath(dp); + + /* Check that port was successfully configured. */ +- return dp_netdev_lookup_port(dp, port_no) ? 0 : EINVAL; ++ if (!dp_netdev_lookup_port(dp, port_no)) { ++ return EINVAL; ++ } ++ ++ /* Updating device flags triggers an if_notifier, which triggers a bridge ++ * reconfiguration and another attempt to add this port, leading to an ++ * infinite loop if the device is configured incorrectly and cannot be ++ * added. Setting the promisc mode after a successful reconfiguration, ++ * since we already know that the device is somehow properly configured. */ ++ error = netdev_turn_flags_on(port->netdev, NETDEV_PROMISC, &sf); ++ if (error) { ++ VLOG_ERR("%s: cannot set promisc flag", devname); ++ do_del_port(dp, port); ++ return error; ++ } ++ port->sf = sf; ++ ++ return 0; + } + + static int +-- +2.14.1 + + diff --git a/dpif-netdev-Do-not-mix-recirculation-depth-into-RSS-.patch b/dpif-netdev-Do-not-mix-recirculation-depth-into-RSS-.patch new file mode 100644 index 0000000..05e3929 --- /dev/null +++ b/dpif-netdev-Do-not-mix-recirculation-depth-into-RSS-.patch @@ -0,0 +1,43 @@ +From 492856b16e0673184987e402c41a42f991853b7c Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Thu, 24 Oct 2019 12:55:15 +0200 +Subject: dpif-netdev: Do not mix recirculation depth into RSS hash itself. + +Mixing of RSS hash with recirculation depth is useful for flow lookup +because same packet after recirculation should match with different +datapath rule. Setting of the mixed value back to the packet is +completely unnecessary because recirculation depth is different on +each recirculation, i.e. we will have different packet hash for +flow lookup anyway. + +This should fix the issue that packets from the same flow could be +directed to different buckets based on a dp_hash or different ports of +a balanced bonding in case they were recirculated different number of +times (e.g. due to conntrack rules). +With this change, the original RSS hash will remain the same making +it possible to calculate equal dp_hash values for such packets. + +Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2019-September/363127.html +Fixes: 048963aa8507 ("dpif-netdev: Reset RSS hash when recirculating.") +Signed-off-by: Ilya Maximets +Acked-by: Jan Scheurich +--- + lib/dpif-netdev.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c +index 133c9b9a4..f71deb718 100644 +--- a/lib/dpif-netdev.c ++++ b/lib/dpif-netdev.c +@@ -6272,7 +6272,6 @@ dpif_netdev_packet_get_rss_hash(struct dp_packet *packet, + recirc_depth = *recirc_depth_get_unsafe(); + if (OVS_UNLIKELY(recirc_depth)) { + hash = hash_finish(hash, recirc_depth); +- dp_packet_set_rss_hash(packet, hash); + } + return hash; + } +-- +2.14.1 + + diff --git a/dpif-netdev-Fix-time-delta-overflow-in-case-of-race-.patch b/dpif-netdev-Fix-time-delta-overflow-in-case-of-race-.patch new file mode 100644 index 0000000..fd4bbd0 --- /dev/null +++ b/dpif-netdev-Fix-time-delta-overflow-in-case-of-race-.patch @@ -0,0 +1,48 @@ +From aa49a6d46edfaeb414fcd70d3138ee8b28ffb343 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Thu, 24 Oct 2019 15:15:07 +0200 +Subject: dpif-netdev: Fix time delta overflow in case of race for meter lock. + +There is a race window between getting the time and getting the meter +lock. This could lead to situation where the thread with larger +current time (this thread called time_{um}sec() later than others) +will acquire meter lock first and update meter->used to the large +value. Next threads will try to calculate time delta by subtracting +the large meter->used from their lower time getting the negative value +which will be converted to a big unsigned delta. + +Fix that by assuming that all these threads received packets in the +same time in this case, i.e. dropping negative delta to 0. + +CC: Jarno Rajahalme +Fixes: 4b27db644a8c ("dpif-netdev: Simple DROP meter implementation.") +Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2019-September/363126.html +Signed-off-by: Ilya Maximets +Acked-by: William Tu +--- + lib/dpif-netdev.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c +index f71deb718..370840fa0 100644 +--- a/lib/dpif-netdev.c ++++ b/lib/dpif-netdev.c +@@ -5630,6 +5630,14 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, + /* All packets will hit the meter at the same time. */ + long_delta_t = now / 1000 - meter->used / 1000; /* msec */ + ++ if (long_delta_t < 0) { ++ /* This condition means that we have several threads fighting for a ++ meter lock, and the one who received the packets a bit later wins. ++ Assuming that all racing threads received packets at the same time ++ to avoid overflow. */ ++ long_delta_t = 0; ++ } ++ + /* Make sure delta_t will not be too large, so that bucket will not + * wrap around below. */ + delta_t = (long_delta_t > (long long int)meter->max_delta_t) +-- +2.14.1 + + diff --git a/dpif-netdev-Handle-uninitialized-value-error-for-mat.patch b/dpif-netdev-Handle-uninitialized-value-error-for-mat.patch new file mode 100644 index 0000000..3322c92 --- /dev/null +++ b/dpif-netdev-Handle-uninitialized-value-error-for-mat.patch @@ -0,0 +1,53 @@ +From 3198ae3f423320cc21d40a995a6693b5fa56aade Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:29 -0700 +Subject: dpif-netdev: Handle uninitialized value error for 'match.wc' + +Valgrind reported that match.wc was not initialized, as below: + +1176: ofproto-dpif - fragment handling - actions + +==21214== Conditional jump or move depends on uninitialised value(s) +==21214== at 0x4B77C1: odp_flow_key_from_flow__ (odp-util.c:6143) +==21214== by 0x46DB58: dp_netdev_upcall (dpif-netdev.c:6239) +==21214== by 0x4774A7: handle_packet_upcall (dpif-netdev.c:6608) +==21214== by 0x4774A7: fast_path_processing (dpif-netdev.c:6726) +==21214== by 0x47933C: dp_netdev_input__ (dpif-netdev.c:6814) +==21214== by 0x479AB8: dp_netdev_input (dpif-netdev.c:6852) +==21214== by 0x479AB8: dp_netdev_process_rxq_port (dpif-netdev.c:4287) +==21214== by 0x47A6A9: dpif_netdev_run (dpif-netdev.c:5264) +==21214== by 0x4324E7: type_run (ofproto-dpif.c:342) +==21214== by 0x41C5FE: ofproto_type_run (ofproto.c:1734) +==21214== by 0x40BAAC: bridge_run__ (bridge.c:2965) +==21214== by 0x410CF3: bridge_run (bridge.c:3029) +==21214== by 0x407614: main (ovs-vswitchd.c:127) +==21214== Uninitialised value was created by a stack allocation +==21214== at 0x4769C3: fast_path_processing (dpif-netdev.c:6672) + +'match' is allocated on stack but its 'wc' is accessed in +odp_flow_key_from_flow__ without proper initialization. +This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + lib/dpif-netdev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c +index 75d85b2fd..133c9b9a4 100644 +--- a/lib/dpif-netdev.c ++++ b/lib/dpif-netdev.c +@@ -6584,6 +6584,7 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd, + + match.tun_md.valid = false; + miniflow_expand(&key->mf, &match.flow); ++ memset(&match.wc, 0, sizeof match.wc); + + ofpbuf_clear(actions); + ofpbuf_clear(put_actions); +-- +2.14.1 + + diff --git a/dpif-netlink-Free-leaked-nl_sock.patch b/dpif-netlink-Free-leaked-nl_sock.patch new file mode 100644 index 0000000..7bf3ee8 --- /dev/null +++ b/dpif-netlink-Free-leaked-nl_sock.patch @@ -0,0 +1,49 @@ +From a73c04ae00b2eb39c91ae6dddb3981e1a14c967e Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Fri, 11 Oct 2019 15:50:47 -0700 +Subject: dpif-netlink: Free leaked nl_sock + +Valgrind reports: +20 bytes in 1 blocks are definitely lost in loss record 94 of 353 + by 0x532594: xmalloc (util.c:138) + by 0x553EAD: nl_sock_create (netlink-socket.c:146) + by 0x54331D: create_nl_sock (dpif-netlink.c:255) + by 0x54331D: dpif_netlink_port_add__ (dpif-netlink.c:756) + by 0x5435F6: dpif_netlink_port_add_compat (dpif-netlink.c:876) + by 0x5435F6: dpif_netlink_port_add (dpif-netlink.c:922) + by 0x47EC1D: dpif_port_add (dpif.c:584) + by 0x42B35F: port_add (ofproto-dpif.c:3721) + by 0x41E64A: ofproto_port_add (ofproto.c:2032) + by 0x40B3FE: iface_do_create (bridge.c:1817) + by 0x40B3FE: iface_create (bridge.c:1855) + by 0x40B3FE: bridge_add_ports__ (bridge.c:943) + by 0x40D14A: bridge_add_ports (bridge.c:959) + by 0x40D14A: bridge_reconfigure (bridge.c:673) + by 0x410D75: bridge_run (bridge.c:3050) + by 0x407614: main (ovs-vswitchd.c:127) + +This leak is because when vport_add_channel() returns 0, it is expected +to take the ownership of 'socksp'. This patch fixes this issue. + +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + lib/dpif-netlink.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c +index 7bc71d6d1..efdb9acfc 100644 +--- a/lib/dpif-netlink.c ++++ b/lib/dpif-netlink.c +@@ -457,6 +457,7 @@ vport_add_channel(struct dpif_netlink *dpif, odp_port_t port_no, + int error; + + if (dpif->handlers == NULL) { ++ close_nl_sock(socksp); + return 0; + } + +-- +2.14.1 + + diff --git a/faq-Update-OVS-DPDK-version-table-for-OVS-2.12.patch b/faq-Update-OVS-DPDK-version-table-for-OVS-2.12.patch new file mode 100644 index 0000000..c76c9c0 --- /dev/null +++ b/faq-Update-OVS-DPDK-version-table-for-OVS-2.12.patch @@ -0,0 +1,29 @@ +From e40063a8c268a937902b29fa32e71335481ea0ff Mon Sep 17 00:00:00 2001 +From: Kevin Traynor +Date: Mon, 23 Sep 2019 16:59:11 +0100 +Subject: faq: Update OVS/DPDK version table for OVS 2.12. + +Indicate that OVS 2.12 uses DPDK 18.11.2. + +Signed-off-by: Kevin Traynor +Signed-off-by: Ben Pfaff +--- + Documentation/faq/releases.rst | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/faq/releases.rst b/Documentation/faq/releases.rst +index 8c29e32ef..e18f5db75 100644 +--- a/Documentation/faq/releases.rst ++++ b/Documentation/faq/releases.rst +@@ -179,6 +179,7 @@ Q: What DPDK version does each Open vSwitch release work with? + 2.9.x 17.11.4 + 2.10.x 17.11.4 + 2.11.x 18.11.2 ++ 2.12.x 18.11.2 + ============ ======= + + Q: Are all the DPDK releases that OVS versions work with maintained? +-- +2.14.1 + + diff --git a/faq-Update-list-of-kernels-supported-by-2.12.patch b/faq-Update-list-of-kernels-supported-by-2.12.patch new file mode 100644 index 0000000..25df1d9 --- /dev/null +++ b/faq-Update-list-of-kernels-supported-by-2.12.patch @@ -0,0 +1,27 @@ +From 25cf170d88f98b8f7a2009d560b017b2b4f5fc83 Mon Sep 17 00:00:00 2001 +From: Justin Pettit +Date: Fri, 6 Sep 2019 16:30:46 -0700 +Subject: faq: Update list of kernels supported by 2.12. + +Signed-off-by: Justin Pettit +Reviewed-by: Yifeng Sun +--- + Documentation/faq/releases.rst | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/faq/releases.rst b/Documentation/faq/releases.rst +index 8daa23bb2..8c29e32ef 100644 +--- a/Documentation/faq/releases.rst ++++ b/Documentation/faq/releases.rst +@@ -69,6 +69,7 @@ Q: What Linux kernel versions does each Open vSwitch release work with? + 2.9.x 3.10 to 4.13 + 2.10.x 3.10 to 4.17 + 2.11.x 3.10 to 4.18 ++ 2.12.x 3.10 to 5.0 + ============ ============== + + Open vSwitch userspace should also work with the Linux kernel module built +-- +2.14.1 + + diff --git a/flow-Fix-IPv6-header-parser-with-partial-offloading.patch b/flow-Fix-IPv6-header-parser-with-partial-offloading.patch new file mode 100644 index 0000000..aff374f --- /dev/null +++ b/flow-Fix-IPv6-header-parser-with-partial-offloading.patch @@ -0,0 +1,34 @@ +From b24353da63d84420b5a103a91d475b4669ad4122 Mon Sep 17 00:00:00 2001 +From: Zhike Wang +Date: Fri, 8 Nov 2019 17:02:44 +0800 +Subject: flow: Fix IPv6 header parser with partial offloading. + +Set nw_proto before it is used in parse_ipv6_ext_hdrs__(). + +Signed-off-by: Zhike Wang +Signed-off-by: Ben Pfaff +--- + lib/flow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/flow.c b/lib/flow.c +index b7f35e33b..6c7c08fd8 100644 +--- a/lib/flow.c ++++ b/lib/flow.c +@@ -1139,11 +1139,11 @@ parse_tcp_flags(struct dp_packet *packet) + dp_packet_set_l2_pad_size(packet, size - plen); + size = plen; + const struct ovs_16aligned_ip6_frag *frag_hdr; ++ nw_proto = nh->ip6_nxt; + if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag, + &frag_hdr)) { + return 0; + } +- nw_proto = nh->ip6_nxt; + } else { + return 0; + } +-- +2.14.1 + + diff --git a/flow-Fix-crash-on-vlan-packets-with-partial-offloadi.patch b/flow-Fix-crash-on-vlan-packets-with-partial-offloadi.patch new file mode 100644 index 0000000..632dc89 --- /dev/null +++ b/flow-Fix-crash-on-vlan-packets-with-partial-offloadi.patch @@ -0,0 +1,186 @@ +From 16c647479e4e4931b45bdaa0b995c9cadb16d5a6 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Wed, 23 Oct 2019 22:26:52 +0200 +Subject: flow: Fix crash on vlan packets with partial offloading. + +parse_tcp_flags() does not care about vlan tags in a packet thus +not able to parse them. As a result, if partial offloading is +enabled in userspace datapath vlan packets are not parsed, i.e. +has no initialized offsets. This causes OVS crash on any attempt +to access/modify packet header fields. + +For example, having the flow with following actions: + in_port=1,ip,actions=mod_nw_src:192.168.0.7,output:IN_PORT + +will lead to OVS crash on vlan packet handling: + + Process terminating with default action of signal 11 (SIGSEGV) + Invalid read of size 4 + at 0x785657: get_16aligned_be32 (unaligned.h:249) + by 0x785657: odp_set_ipv4 (odp-execute.c:82) + by 0x785657: odp_execute_masked_set_action (odp-execute.c:527) + by 0x785657: odp_execute_actions (odp-execute.c:894) + by 0x74CDA9: dp_netdev_execute_actions (dpif-netdev.c:7355) + by 0x74CDA9: packet_batch_per_flow_execute (dpif-netdev.c:6339) + by 0x74CDA9: dp_netdev_input__ (dpif-netdev.c:6845) + by 0x74DB6E: dp_netdev_input (dpif-netdev.c:6854) + by 0x74DB6E: dp_netdev_process_rxq_port (dpif-netdev.c:4287) + by 0x74E863: dpif_netdev_run (dpif-netdev.c:5264) + by 0x703F57: type_run (ofproto-dpif.c:370) + by 0x6EC8B8: ofproto_type_run (ofproto.c:1760) + by 0x6DA52B: bridge_run__ (bridge.c:3188) + by 0x6E083F: bridge_run (bridge.c:3252) + by 0x1642E4: main (ovs-vswitchd.c:127) + Address 0xc is not stack'd, malloc'd or (recently) free'd + +Fix that by properly parsing vlan tags first. Function 'parse_dl_type' +transformed for that purpose as it had no users anyway. + +Added unit test for packet modification with partial offloading that +triggers above crash. + +Fixes: aab96ec4d81e ("dpif-netdev: retrieve flow directly from the flow mark") +Signed-off-by: Ilya Maximets +Acked-by: Ben Pfaff +--- + lib/flow.c | 12 ++++---- + lib/flow.h | 1 - + tests/dpif-netdev.at | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 83 insertions(+), 8 deletions(-) + +diff --git a/lib/flow.c b/lib/flow.c +index 0ba146272..b7f35e33b 100644 +--- a/lib/flow.c ++++ b/lib/flow.c +@@ -1076,15 +1076,14 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) + dst->map = mf.map; + } + +-ovs_be16 +-parse_dl_type(const struct eth_header *data_, size_t size) ++static ovs_be16 ++parse_dl_type(const void **datap, size_t *sizep) + { +- const void *data = data_; + union flow_vlan_hdr vlans[FLOW_MAX_VLAN_HEADERS]; + +- parse_vlan(&data, &size, vlans); ++ parse_vlan(datap, sizep, vlans); + +- return parse_ethertype(&data, &size); ++ return parse_ethertype(datap, sizep); + } + + /* Parses and return the TCP flags in 'packet', converted to host byte order. +@@ -1107,8 +1106,7 @@ parse_tcp_flags(struct dp_packet *packet) + + dp_packet_reset_offsets(packet); + +- data_pull(&data, &size, ETH_ADDR_LEN * 2); +- dl_type = parse_ethertype(&data, &size); ++ dl_type = parse_dl_type(&data, &size); + if (OVS_UNLIKELY(eth_type_mpls(dl_type))) { + packet->l2_5_ofs = (char *)data - frame; + } +diff --git a/lib/flow.h b/lib/flow.h +index 7298c71f3..75751763c 100644 +--- a/lib/flow.h ++++ b/lib/flow.h +@@ -133,7 +133,6 @@ void packet_expand(struct dp_packet *, const struct flow *, size_t size); + bool parse_ipv6_ext_hdrs(const void **datap, size_t *sizep, uint8_t *nw_proto, + uint8_t *nw_frag, + const struct ovs_16aligned_ip6_frag **frag_hdr); +-ovs_be16 parse_dl_type(const struct eth_header *data_, size_t size); + bool parse_nsh(const void **datap, size_t *sizep, struct ovs_key_nsh *key); + uint16_t parse_tcp_flags(struct dp_packet *packet); + +diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at +index af8a29e44..ef521ddb8 100644 +--- a/tests/dpif-netdev.at ++++ b/tests/dpif-netdev.at +@@ -420,3 +420,81 @@ p1: flow del: mark: 0 + + DPIF_NETDEV_FLOW_HW_OFFLOAD([dummy]) + DPIF_NETDEV_FLOW_HW_OFFLOAD([dummy-pmd]) ++ ++ ++m4_define([DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS], ++ [AT_SETUP([dpif-netdev - partial hw offload with packet modifications - $1]) ++ OVS_VSWITCHD_START( ++ [add-port br0 p1 -- \ ++ set interface p1 type=$1 ofport_request=1 options:pcap=p1.pcap options:ifindex=1 -- \ ++ set bridge br0 datapath-type=dummy \ ++ other-config:datapath-id=1234 fail-mode=secure], [], [], ++ [m4_if([$1], [dummy-pmd], [--dummy-numa="0,0,0,0,1,1,1,1"], [])]) ++ AT_CHECK([ovs-appctl vlog/set dpif:file:dbg dpif_netdev:file:dbg netdev_dummy:file:dbg]) ++ ++ AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true]) ++ OVS_WAIT_UNTIL([grep "netdev: Flow API Enabled" ovs-vswitchd.log]) ++ ++ AT_CHECK([ovs-ofctl del-flows br0]) ++ ++ # Setting flow to modify ipv4 src address and udp dst port to be sure that ++ # offloaded packets has correctly initialized l3/l4 offsets. ++ AT_CHECK([ovs-ofctl add-flow br0 in_port=1,udp,actions=mod_nw_src:192.168.0.7,mod_tp_dst:3773,output:IN_PORT]) ++ ++ packet="packet_type(ns=0,id=0),eth(src=00:06:07:08:09:0a,dst=00:01:02:03:04:05),eth_type(0x8100),vlan(vid=99,pcp=7),encap(eth_type(0x0800),ipv4(src=127.0.0.1,dst=127.0.0.1,proto=17,ttl=64,frag=no),udp(src=81,dst=82))" ++ AT_CHECK([ovs-appctl netdev-dummy/receive p1 $packet --len 64], [0]) ++ ++ OVS_WAIT_UNTIL([grep "miss upcall" ovs-vswitchd.log]) ++ AT_CHECK([grep -A 1 'miss upcall' ovs-vswitchd.log | tail -n 1], [0], [dnl ++skb_priority(0),skb_mark(0),ct_state(0),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),dnl ++packet_type(ns=0,id=0),eth(src=00:06:07:08:09:0a,dst=00:01:02:03:04:05),eth_type(0x8100),vlan(vid=99,pcp=7),encap(eth_type(0x0800),ipv4(src=127.0.0.1,dst=127.0.0.1,proto=17,tos=0,ttl=64,frag=no),udp(src=81,dst=82)) ++]) ++ # Check that flow successfully offloaded. ++ OVS_WAIT_UNTIL([grep "succeed to add netdev flow" ovs-vswitchd.log]) ++ AT_CHECK([filter_hw_flow_install < ovs-vswitchd.log | strip_xout], [0], [dnl ++p1: flow put[[create]]: flow match: recirc_id=0,eth,udp,in_port=1,dl_vlan=99,dl_vlan_pcp=7,nw_src=127.0.0.1,nw_frag=no,tp_dst=82, mark: 0 ++]) ++ # Check that datapath flow installed successfully. ++ AT_CHECK([filter_flow_install < ovs-vswitchd.log | strip_xout], [0], [dnl ++recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x8100),vlan(vid=99,pcp=7),encap(eth_type(0x0800),ipv4(src=127.0.0.1,proto=17,frag=no),udp(dst=82)), actions: ++]) ++ # Inject the same packet again. ++ AT_CHECK([ovs-appctl netdev-dummy/receive p1 $packet --len 64], [0]) ++ ++ # Check for succesfull packet matching with installed offloaded flow. ++ AT_CHECK([filter_hw_packet_netdev_dummy < ovs-vswitchd.log | strip_xout], [0], [dnl ++p1: packet: udp,dl_vlan=99,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:0a,dl_dst=00:01:02:03:04:05,nw_src=127.0.0.1,nw_dst=127.0.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=81,tp_dst=82 dnl ++matches with flow: recirc_id=0,eth,udp,dl_vlan=99,dl_vlan_pcp=7,nw_src=127.0.0.1,nw_frag=no,tp_dst=82 with mark: 0 ++]) ++ ++ ovs-appctl revalidator/wait ++ # Dump the datapath flow to see that actions was executed for a packet. ++ AT_CHECK([ovs-appctl dpif/dump-flows br0 | strip_timers], [0], [dnl ++recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x8100),vlan(vid=99,pcp=7),encap(eth_type(0x0800),ipv4(src=127.0.0.1,proto=17,frag=no),udp(dst=82)), dnl ++packets:1, bytes:64, used:0.0s, actions:set(ipv4(src=192.168.0.7)),set(udp(dst=3773)),1 ++]) ++ ++ # Wait for datapath flow expiration. ++ ovs-appctl time/stop ++ ovs-appctl time/warp 15000 ++ ovs-appctl revalidator/wait ++ ++ # Check that flow successfully deleted from HW. ++ OVS_WAIT_UNTIL([grep "succeed to delete netdev flow" ovs-vswitchd.log]) ++ AT_CHECK([filter_hw_flow_del < ovs-vswitchd.log | strip_xout], [0], [dnl ++p1: flow del: mark: 0 ++]) ++ ++ # Check that ip address and udp port were correctly modified in output packets. ++ AT_CHECK([ovs-ofctl parse-pcap p1.pcap], [0], [dnl ++udp,in_port=ANY,dl_vlan=99,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:0a,dl_dst=00:01:02:03:04:05,nw_src=127.0.0.1,nw_dst=127.0.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=81,tp_dst=82 ++udp,in_port=ANY,dl_vlan=99,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:0a,dl_dst=00:01:02:03:04:05,nw_src=192.168.0.7,nw_dst=127.0.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=81,tp_dst=3773 ++udp,in_port=ANY,dl_vlan=99,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:0a,dl_dst=00:01:02:03:04:05,nw_src=127.0.0.1,nw_dst=127.0.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=81,tp_dst=82 ++udp,in_port=ANY,dl_vlan=99,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:0a,dl_dst=00:01:02:03:04:05,nw_src=192.168.0.7,nw_dst=127.0.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=81,tp_dst=3773 ++]) ++ ++ OVS_VSWITCHD_STOP ++ AT_CLEANUP]) ++ ++DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS([dummy]) ++DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS([dummy-pmd]) +-- +2.14.1 + + diff --git a/flow-Fix-using-pointer-to-member-of-packed-struct-ic.patch b/flow-Fix-using-pointer-to-member-of-packed-struct-ic.patch new file mode 100644 index 0000000..0e4c6d4 --- /dev/null +++ b/flow-Fix-using-pointer-to-member-of-packed-struct-ic.patch @@ -0,0 +1,256 @@ +From f94b6e0f9997b5c0f9a278f1f365462dff03da51 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Tue, 1 Oct 2019 18:18:23 +0300 +Subject: flow: Fix using pointer to member of packed struct icmp6_hdr. + +OVS has no structure definition for ICMPv6 header with additional +data. More precisely, it has, but this structure named as +'icmp6_error_header' and only suitable to store error related +extended information. 'flow_compose_l4' stores additional +information in reserved bits by using system defined structure +'icmp6_hdr', which is marked as 'packed' and this leads to +build failure with gcc >= 9: + + lib/flow.c:3041:34: error: + taking address of packed member of 'struct icmp6_hdr' may result + in an unaligned pointer value [-Werror=address-of-packed-member] + + uint32_t *reserved = &icmp->icmp6_dataun.icmp6_un_data32[0]; + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Fix that by renaming 'icmp6_error_header' to 'icmp6_data_header' +and allowing it to store not only errors, but any type of additional +information by analogue with 'struct icmp6_hdr'. +All the usages of 'struct icmp6_hdr' replaced with this new structure. +Removed redundant conversions between network and host representations. +Now fields are always in be. + +This also, probably, makes flow_compose_l4 more robust by avoiding +possible unaligned accesses to 32 bit value. + +Fixes: 9b2b84973db7 ("Support for match & set ICMPv6 reserved and options type fields") +Signed-off-by: Ilya Maximets +Acked-by: William Tu +Acked-by: Ben Pfaff +--- + lib/conntrack.c | 2 +- + lib/flow.c | 77 ++++++++++++++++++++++++------------------------ + lib/packets.h | 12 +++++--- + ovn/controller/pinctrl.c | 6 ++-- + 4 files changed, 51 insertions(+), 46 deletions(-) + +diff --git a/lib/conntrack.c b/lib/conntrack.c +index b56ef06ac..43fd510ef 100644 +--- a/lib/conntrack.c ++++ b/lib/conntrack.c +@@ -718,7 +718,7 @@ reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn) + icmp->icmp_csum = csum(icmp, tail - (char *) icmp - pad); + } else { + struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt); +- struct icmp6_error_header *icmp6 = dp_packet_l4(pkt); ++ struct icmp6_data_header *icmp6 = dp_packet_l4(pkt); + struct ovs_16aligned_ip6_hdr *inner_l3_6 = + (struct ovs_16aligned_ip6_hdr *) (icmp6 + 1); + /* This call is already verified to succeed during the code path from +diff --git a/lib/flow.c b/lib/flow.c +index db84b01f2..0ba146272 100644 +--- a/lib/flow.c ++++ b/lib/flow.c +@@ -399,14 +399,14 @@ parse_ethertype(const void **datap, size_t *sizep) + * and 'arp_buf[]' are filled in. If the packet is not an ND packet, 'false' + * is returned and no values are filled in on '*nd_target' or 'arp_buf[]'. */ + static inline bool +-parse_icmpv6(const void **datap, size_t *sizep, const struct icmp6_hdr *icmp, +- uint32_t *rso_flags, const struct in6_addr **nd_target, ++parse_icmpv6(const void **datap, size_t *sizep, ++ const struct icmp6_data_header *icmp6, ++ ovs_be32 *rso_flags, const struct in6_addr **nd_target, + struct eth_addr arp_buf[2], uint8_t *opt_type) + { +- const uint32_t *reserved; +- if (icmp->icmp6_code != 0 || +- (icmp->icmp6_type != ND_NEIGHBOR_SOLICIT && +- icmp->icmp6_type != ND_NEIGHBOR_ADVERT)) { ++ if (icmp6->icmp6_base.icmp6_code != 0 || ++ (icmp6->icmp6_base.icmp6_type != ND_NEIGHBOR_SOLICIT && ++ icmp6->icmp6_base.icmp6_type != ND_NEIGHBOR_ADVERT)) { + return false; + } + +@@ -414,12 +414,7 @@ parse_icmpv6(const void **datap, size_t *sizep, const struct icmp6_hdr *icmp, + arp_buf[1] = eth_addr_zero; + *opt_type = 0; + +- reserved = data_try_pull(datap, sizep, sizeof(uint32_t)); +- if (OVS_UNLIKELY(!reserved)) { +- /* Invalid ND packet. */ +- return false; +- } +- *rso_flags = *reserved; ++ *rso_flags = get_16aligned_be32(icmp6->icmp6_data.be32); + + *nd_target = data_try_pull(datap, sizep, sizeof **nd_target); + if (OVS_UNLIKELY(!*nd_target)) { +@@ -1027,17 +1022,18 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) + miniflow_pad_to_64(mf, igmp_group_ip4); + } + } else if (OVS_LIKELY(nw_proto == IPPROTO_ICMPV6)) { +- if (OVS_LIKELY(size >= sizeof(struct icmp6_hdr))) { ++ if (OVS_LIKELY(size >= sizeof(struct icmp6_data_header))) { + const struct in6_addr *nd_target; + struct eth_addr arp_buf[2]; + /* This will populate whether we received Option 1 + * or Option 2. */ + uint8_t opt_type; + /* This holds the ND Reserved field. */ +- uint32_t rso_flags; +- const struct icmp6_hdr *icmp = data_pull(&data, +- &size,ICMP6_HEADER_LEN); +- if (parse_icmpv6(&data, &size, icmp, ++ ovs_be32 rso_flags; ++ const struct icmp6_data_header *icmp6; ++ ++ icmp6 = data_pull(&data, &size, sizeof *icmp6); ++ if (parse_icmpv6(&data, &size, icmp6, + &rso_flags, &nd_target, arp_buf, &opt_type)) { + if (nd_target) { + miniflow_push_words(mf, nd_target, nd_target, +@@ -1056,16 +1052,20 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) + * This will zero out the tcp_flags & pad3 field. */ + miniflow_pad_to_64(mf, arp_tha); + } +- miniflow_push_be16(mf, tp_src, htons(icmp->icmp6_type)); +- miniflow_push_be16(mf, tp_dst, htons(icmp->icmp6_code)); ++ miniflow_push_be16(mf, tp_src, ++ htons(icmp6->icmp6_base.icmp6_type)); ++ miniflow_push_be16(mf, tp_dst, ++ htons(icmp6->icmp6_base.icmp6_code)); + miniflow_pad_to_64(mf, tp_dst); + /* Fill ND reserved field. */ +- miniflow_push_be32(mf, igmp_group_ip4, htonl(rso_flags)); ++ miniflow_push_be32(mf, igmp_group_ip4, rso_flags); + miniflow_pad_to_64(mf, igmp_group_ip4); + } else { + /* ICMPv6 but not ND. */ +- miniflow_push_be16(mf, tp_src, htons(icmp->icmp6_type)); +- miniflow_push_be16(mf, tp_dst, htons(icmp->icmp6_code)); ++ miniflow_push_be16(mf, tp_src, ++ htons(icmp6->icmp6_base.icmp6_type)); ++ miniflow_push_be16(mf, tp_dst, ++ htons(icmp6->icmp6_base.icmp6_code)); + miniflow_push_be16(mf, ct_tp_src, ct_tp_src); + miniflow_push_be16(mf, ct_tp_dst, ct_tp_dst); + } +@@ -3038,15 +3038,16 @@ flow_compose_l4(struct dp_packet *p, const struct flow *flow, + igmp->igmp_code = ntohs(flow->tp_dst); + put_16aligned_be32(&igmp->group, flow->igmp_group_ip4); + } else if (flow->nw_proto == IPPROTO_ICMPV6) { +- struct icmp6_hdr *icmp = dp_packet_put_zeros(p, sizeof *icmp); +- icmp->icmp6_type = ntohs(flow->tp_src); +- icmp->icmp6_code = ntohs(flow->tp_dst); +- uint32_t *reserved = &icmp->icmp6_dataun.icmp6_un_data32[0]; +- *reserved = ntohl(flow->igmp_group_ip4); +- +- if (icmp->icmp6_code == 0 && +- (icmp->icmp6_type == ND_NEIGHBOR_SOLICIT || +- icmp->icmp6_type == ND_NEIGHBOR_ADVERT)) { ++ struct icmp6_data_header *icmp6; ++ ++ icmp6 = dp_packet_put_zeros(p, sizeof *icmp6); ++ icmp6->icmp6_base.icmp6_type = ntohs(flow->tp_src); ++ icmp6->icmp6_base.icmp6_code = ntohs(flow->tp_dst); ++ put_16aligned_be32(icmp6->icmp6_data.be32, flow->igmp_group_ip4); ++ ++ if (icmp6->icmp6_base.icmp6_code == 0 && ++ (icmp6->icmp6_base.icmp6_type == ND_NEIGHBOR_SOLICIT || ++ icmp6->icmp6_base.icmp6_type == ND_NEIGHBOR_ADVERT)) { + struct in6_addr *nd_target; + struct ovs_nd_lla_opt *lla_opt; + +@@ -3065,9 +3066,9 @@ flow_compose_l4(struct dp_packet *p, const struct flow *flow, + lla_opt->type = ND_OPT_TARGET_LINKADDR; + lla_opt->mac = flow->arp_tha; + } +- } else if (icmp->icmp6_code == 0 && +- (icmp->icmp6_type == ICMP6_ECHO_REQUEST || +- icmp->icmp6_type == ICMP6_ECHO_REPLY)) { ++ } else if (icmp6->icmp6_base.icmp6_code == 0 && ++ (icmp6->icmp6_base.icmp6_type == ICMP6_ECHO_REQUEST || ++ icmp6->icmp6_base.icmp6_type == ICMP6_ECHO_REPLY)) { + flow_compose_l7(p, l7, l7_len); + } else { + /* XXX Add inner IP packet for e.g. destination unreachable? */ +@@ -3112,11 +3113,11 @@ flow_compose_l4_csum(struct dp_packet *p, const struct flow *flow, + igmp->igmp_csum = 0; + igmp->igmp_csum = csum(igmp, l4_len); + } else if (flow->nw_proto == IPPROTO_ICMPV6) { +- struct icmp6_hdr *icmp = dp_packet_l4(p); ++ struct icmp6_data_header *icmp6 = dp_packet_l4(p); + +- icmp->icmp6_cksum = 0; +- icmp->icmp6_cksum = (OVS_FORCE uint16_t) +- csum_finish(csum_continue(pseudo_hdr_csum, icmp, l4_len)); ++ icmp6->icmp6_base.icmp6_cksum = 0; ++ icmp6->icmp6_base.icmp6_cksum = ++ csum_finish(csum_continue(pseudo_hdr_csum, icmp6, l4_len)); + } + } + } +diff --git a/lib/packets.h b/lib/packets.h +index 05040a8e0..648dbd770 100644 +--- a/lib/packets.h ++++ b/lib/packets.h +@@ -961,12 +961,16 @@ struct icmp6_header { + }; + BUILD_ASSERT_DECL(ICMP6_HEADER_LEN == sizeof(struct icmp6_header)); + +-#define ICMP6_ERROR_HEADER_LEN 8 +-struct icmp6_error_header { ++#define ICMP6_DATA_HEADER_LEN 8 ++struct icmp6_data_header { + struct icmp6_header icmp6_base; +- ovs_be32 icmp6_error_ext; ++ union { ++ ovs_16aligned_be32 be32[1]; ++ ovs_be16 be16[2]; ++ uint8_t u8[4]; ++ } icmp6_data; + }; +-BUILD_ASSERT_DECL(ICMP6_ERROR_HEADER_LEN == sizeof(struct icmp6_error_header)); ++BUILD_ASSERT_DECL(ICMP6_DATA_HEADER_LEN == sizeof(struct icmp6_data_header)); + + uint32_t packet_csum_pseudoheader6(const struct ovs_16aligned_ip6_hdr *); + ovs_be16 packet_csum_upperlayer6(const struct ovs_16aligned_ip6_hdr *, +diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c +index af68f0f6b..d74e0bc7a 100644 +--- a/ovn/controller/pinctrl.c ++++ b/ovn/controller/pinctrl.c +@@ -842,14 +842,14 @@ pinctrl_handle_icmp(struct rconn *swconn, const struct flow *ip_flow, + } + } else { + struct ip6_hdr *nh = dp_packet_put_zeros(&packet, sizeof *nh); +- struct icmp6_error_header *ih; ++ struct icmp6_data_header *ih; + uint32_t icmpv6_csum; + + eh->eth_type = htons(ETH_TYPE_IPV6); + dp_packet_set_l3(&packet, nh); + nh->ip6_vfc = 0x60; + nh->ip6_nxt = IPPROTO_ICMPV6; +- nh->ip6_plen = htons(sizeof(*nh) + ICMP6_ERROR_HEADER_LEN); ++ nh->ip6_plen = htons(sizeof(*nh) + ICMP6_DATA_HEADER_LEN); + packet_set_ipv6(&packet, &ip_flow->ipv6_src, &ip_flow->ipv6_dst, + ip_flow->nw_tos, ip_flow->ipv6_label, 255); + +@@ -865,7 +865,7 @@ pinctrl_handle_icmp(struct rconn *swconn, const struct flow *ip_flow, + icmpv6_csum = packet_csum_pseudoheader6(dp_packet_l3(&packet)); + ih->icmp6_base.icmp6_cksum = csum_finish( + csum_continue(icmpv6_csum, ih, +- sizeof(*nh) + ICMP6_ERROR_HEADER_LEN)); ++ sizeof(*nh) + ICMP6_DATA_HEADER_LEN)); + } + + if (ip_flow->vlans[0].tci & htons(VLAN_CFI)) { +-- +2.14.1 + + diff --git a/flow-fix-incorrect-padding-length-checking-in-ipv6_s.patch b/flow-fix-incorrect-padding-length-checking-in-ipv6_s.patch new file mode 100644 index 0000000..ac0e70a --- /dev/null +++ b/flow-fix-incorrect-padding-length-checking-in-ipv6_s.patch @@ -0,0 +1,33 @@ +From 3c22f70994279bc206a78d9a1f40702beb9864d1 Mon Sep 17 00:00:00 2001 +From: Yanqin Wei +Date: Mon, 2 Sep 2019 16:36:47 +0800 +Subject: flow: fix incorrect padding length checking in ipv6_sanity_check + +The padding length is (packet size - ipv6 header length - ipv6 plen). This +patch fixes incorrect padding size checking in ipv6_sanity_check. + +Acked-by: William Tu +Reviewed-by: Gavin Hu +Signed-off-by: Yanqin Wei +Signed-off-by: Ben Pfaff +--- + lib/flow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/flow.c b/lib/flow.c +index e54fd2e52..db84b01f2 100644 +--- a/lib/flow.c ++++ b/lib/flow.c +@@ -699,7 +699,7 @@ ipv6_sanity_check(const struct ovs_16aligned_ip6_hdr *nh, size_t size) + return false; + } + /* Jumbo Payload option not supported yet. */ +- if (OVS_UNLIKELY(size - plen > UINT8_MAX)) { ++ if (OVS_UNLIKELY(size - (plen + IPV6_HEADER_LEN) > UINT8_MAX)) { + return false; + } + +-- +2.14.1 + + diff --git a/ipf-bail-out-when-ipf-state-is-COMPLETED.patch b/ipf-bail-out-when-ipf-state-is-COMPLETED.patch new file mode 100644 index 0000000..58e1297 --- /dev/null +++ b/ipf-bail-out-when-ipf-state-is-COMPLETED.patch @@ -0,0 +1,41 @@ +From af2cab63f95dfd84f3ae105524bd3fb7377a7391 Mon Sep 17 00:00:00 2001 +From: Li RongQing +Date: Thu, 14 Nov 2019 17:18:18 +0800 +Subject: ipf: bail out when ipf state is COMPLETED + +it is easy to crash ovs when a packet with same id +hits a list that already reassembled completedly +but have not been sent out yet, and this packet is +not duplicate with this hit ipf list due to bigger +offset + + 1 0x00007f9fef0ae2d9 in __GI_abort () at abort.c:89 + 2 0x0000000000464042 in ipf_list_state_transition at lib/ipf.c:545 + +Fixes: 4ea96698f667 ("Userspace datapath: Add fragmentation handling.") +Co-authored-by: Wang Li +Signed-off-by: Wang Li +Signed-off-by: Li RongQing +Signed-off-by: Ben Pfaff +--- + lib/ipf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/ipf.c b/lib/ipf.c +index 4cc0f2df6..45c489122 100644 +--- a/lib/ipf.c ++++ b/lib/ipf.c +@@ -899,7 +899,8 @@ ipf_handle_frag(struct ipf *ipf, struct dp_packet *pkt, ovs_be16 dl_type, + MIN(max_frag_list_size, IPF_FRAG_LIST_MIN_INCREMENT)); + hmap_insert(&ipf->frag_lists, &ipf_list->node, hash); + ipf_expiry_list_add(&ipf->frag_exp_list, ipf_list, now); +- } else if (ipf_list->state == IPF_LIST_STATE_REASS_FAIL) { ++ } else if (ipf_list->state == IPF_LIST_STATE_REASS_FAIL || ++ ipf_list->state == IPF_LIST_STATE_COMPLETED) { + /* Bail out as early as possible. */ + return false; + } else if (ipf_list->last_inuse_idx + 1 >= ipf_list->size) { +-- +2.14.1 + + diff --git a/jsonrpc-increase-input-buffer-size-from-512-to-4096.patch b/jsonrpc-increase-input-buffer-size-from-512-to-4096.patch new file mode 100644 index 0000000..b81b584 --- /dev/null +++ b/jsonrpc-increase-input-buffer-size-from-512-to-4096.patch @@ -0,0 +1,32 @@ +From a451bfa8b0b7d5930d92497eccd29a6d2b781b8b Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 6 Nov 2019 11:19:44 +0200 +Subject: jsonrpc: increase input buffer size from 512 to 4096 + +Increase jsonrpc input buffer size from 512 to 4096 bytes in order to +reduce the syscall overhead when downloading huge db size + +Acked-by: Mark Michelson +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Ben Pfaff +--- + lib/jsonrpc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c +index b9619b822..ed748dbde 100644 +--- a/lib/jsonrpc.c ++++ b/lib/jsonrpc.c +@@ -43,7 +43,7 @@ struct jsonrpc { + + /* Input. */ + struct byteq input; +- uint8_t input_buffer[512]; ++ uint8_t input_buffer[4096]; + struct json_parser *parser; + + /* Output. */ +-- +2.14.1 + + diff --git a/lflow.c-Fix-memory-leak-of-lflow_ref_list_node-ref_n.patch b/lflow.c-Fix-memory-leak-of-lflow_ref_list_node-ref_n.patch new file mode 100644 index 0000000..a1bb352 --- /dev/null +++ b/lflow.c-Fix-memory-leak-of-lflow_ref_list_node-ref_n.patch @@ -0,0 +1,50 @@ +From e4c825d1826d8de5dfec9534b18421de4e46b300 Mon Sep 17 00:00:00 2001 +From: Han Zhou +Date: Wed, 30 Oct 2019 22:51:12 -0700 +Subject: lflow.c: Fix memory leak of lflow_ref_list_node->ref_name. + +The ref_name is copied in lflow_resource_add(), but forgot to free in +lflow_resource_destroy_lflow(). It can be fixed by freeing it in +lflow_resource_destroy_lflow(). However, this field is never really +used, so just delete it from lflow_ref_list_node, together with the +"type" field. + +Fixes: 43e6900a7991 ("ovn-controller: Maintain resource references for logical flows.") +Acked-by: Numan Siddique +Signed-off-by: Han Zhou +Signed-off-by: Ben Pfaff +--- + ovn/controller/lflow.c | 2 -- + ovn/controller/lflow.h | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c +index 1aafafb33..dd72a5b46 100644 +--- a/ovn/controller/lflow.c ++++ b/ovn/controller/lflow.c +@@ -230,8 +230,6 @@ lflow_resource_add(struct lflow_resource_ref *lfrr, enum ref_type type, + } + + struct lflow_ref_list_node *lrln = xzalloc(sizeof *lrln); +- lrln->type = type; +- lrln->ref_name = xstrdup(ref_name); + lrln->lflow_uuid = *lflow_uuid; + ovs_list_push_back(&rlfn->ref_lflow_head, &lrln->ref_list); + ovs_list_push_back(&lfrn->lflow_ref_head, &lrln->lflow_list); +diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h +index 4e1086eb6..752bd5906 100644 +--- a/ovn/controller/lflow.h ++++ b/ovn/controller/lflow.h +@@ -79,8 +79,6 @@ enum ref_type { + struct lflow_ref_list_node { + struct ovs_list lflow_list; /* list for same lflow */ + struct ovs_list ref_list; /* list for same ref */ +- enum ref_type type; +- char *ref_name; + struct uuid lflow_uuid; + }; + +-- +2.14.1 + + diff --git a/lib-tc-Fix-flow-dump-for-tunnel-id-equal-zero.patch b/lib-tc-Fix-flow-dump-for-tunnel-id-equal-zero.patch new file mode 100644 index 0000000..6f17165 --- /dev/null +++ b/lib-tc-Fix-flow-dump-for-tunnel-id-equal-zero.patch @@ -0,0 +1,32 @@ +From 9de253c75f2ed8fe298a49e0927e079369f17d31 Mon Sep 17 00:00:00 2001 +From: Dmytro Linkin +Date: Wed, 30 Oct 2019 14:40:35 +0200 +Subject: lib/tc: Fix flow dump for tunnel id equal zero + +Tunnel id 0 is not printed unless tunnel flag FLOW_TNL_F_KEY is set. +Fix that by always setting FLOW_TNL_F_KEY when tunnel id is valid. + +Fixes: 0227bf092ee6 ("lib/tc: Support optional tunnel id") +Signed-off-by: Dmytro Linkin +Reviewed-by: Roi Dayan +Signed-off-by: Simon Horman +--- + lib/netdev-offload-tc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c +index a6b03015d..45d02ba21 100644 +--- a/lib/netdev-offload-tc.c ++++ b/lib/netdev-offload-tc.c +@@ -600,6 +600,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, + if (flower->tunnel) { + if (flower->mask.tunnel.id) { + match_set_tun_id(match, flower->key.tunnel.id); ++ match->flow.tunnel.flags |= FLOW_TNL_F_KEY; + } + if (flower->key.tunnel.ipv4.ipv4_dst) { + match_set_tun_src(match, flower->key.tunnel.ipv4.ipv4_src); +-- +2.14.1 + + diff --git a/lldp-Fix-for-OVS-crashes-when-a-LLDP-enabled-port-is.patch b/lldp-Fix-for-OVS-crashes-when-a-LLDP-enabled-port-is.patch new file mode 100644 index 0000000..4d72540 --- /dev/null +++ b/lldp-Fix-for-OVS-crashes-when-a-LLDP-enabled-port-is.patch @@ -0,0 +1,78 @@ +From 3642294da976cf090755e9df823fd67d0ff86e4d Mon Sep 17 00:00:00 2001 +From: Surya Rudra +Date: Mon, 21 Oct 2019 12:42:02 +0530 +Subject: lldp: Fix for OVS crashes when a LLDP-enabled port is deleted + +Issue: +When LLDP is enabled on a port, a structure to hold LLDP related state +is created and that structure has a reference to the port. The ofproto +monitor thread accesses the LLDP structure to periodically send packets +over the associated port. When the port is deleted, the LLDP structure +is not cleaned up and it continues to refer to the deleted port. + +When the monitor thread attempts to access the deleted port OVS crashes. +Crash can happen with bridge delete and bond delete also. + +Fix: +Remove all references to the LLDP structure and free it when +the port is deleted. + +Signed-off-by: Surya Rudra +Signed-off-by: Ben Pfaff +--- + ofproto/ofproto-dpif.c | 10 +++++----- + ofproto/ofproto.c | 3 +++ + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c +index 7bb0f7bdb..a8c7369d0 100644 +--- a/ofproto/ofproto-dpif.c ++++ b/ofproto/ofproto-dpif.c +@@ -2280,24 +2280,24 @@ set_lldp(struct ofport *ofport_, + const struct smap *cfg) + { + struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); ++ struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto); + int error = 0; + + if (cfg) { + if (!ofport->lldp) { +- struct ofproto_dpif *ofproto; +- +- ofproto = ofproto_dpif_cast(ofport->up.ofproto); + ofproto->backer->need_revalidate = REV_RECONFIGURE; + ofport->lldp = lldp_create(ofport->up.netdev, ofport_->mtu, cfg); + } + + if (!lldp_configure(ofport->lldp, cfg)) { ++ lldp_unref(ofport->lldp); ++ ofport->lldp = NULL; + error = EINVAL; + } +- } +- if (error) { ++ } else if (ofport->lldp) { + lldp_unref(ofport->lldp); + ofport->lldp = NULL; ++ ofproto->backer->need_revalidate = REV_RECONFIGURE; + } + + ofproto_dpif_monitor_port_update(ofport, +diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c +index 1d6fc0069..6ffaced18 100644 +--- a/ofproto/ofproto.c ++++ b/ofproto/ofproto.c +@@ -2511,6 +2511,9 @@ ofproto_port_unregister(struct ofproto *ofproto, ofp_port_t ofp_port) + { + struct ofport *port = ofproto_get_port(ofproto, ofp_port); + if (port) { ++ if (port->ofproto->ofproto_class->set_lldp) { ++ port->ofproto->ofproto_class->set_lldp(port, NULL); ++ } + if (port->ofproto->ofproto_class->set_stp_port) { + port->ofproto->ofproto_class->set_stp_port(port, NULL); + } +-- +2.14.1 + + diff --git a/netdev-afxdp-Avoid-removing-of-XDP-program-if-not-lo.patch b/netdev-afxdp-Avoid-removing-of-XDP-program-if-not-lo.patch new file mode 100644 index 0000000..2010cfb --- /dev/null +++ b/netdev-afxdp-Avoid-removing-of-XDP-program-if-not-lo.patch @@ -0,0 +1,61 @@ +From c0ce219ead0086f1bf79ff6071df1822ee0804c9 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Sat, 7 Dec 2019 15:46:17 +0100 +Subject: netdev-afxdp: Avoid removing of XDP program if not loaded. + +'bpf_set_link_xdp_fd' generates netlink event regardless of actual +changes it does, so if-notifier will receive link update even if +there was no XDP program previously loaded on the interface. + +OVS tries to remove XDP program if device configuration was not +successful triggering if-notifier that triggers bridge reconfiguration +and another attempt to add failed port. And so on in the infinite +loop. + +This patch avoids the issue by not removing XDP program if it wasn't +loaded. Since loading of the XDP program is one of the last steps +of port configuration, this should help to avoid infinite re-addition +for most types of misconfiguration. + +Signed-off-by: Ilya Maximets +Acked-by: William Tu +--- + lib/netdev-afxdp.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c +index 7b452c459..ad66e8e7c 100644 +--- a/lib/netdev-afxdp.c ++++ b/lib/netdev-afxdp.c +@@ -568,7 +568,7 @@ netdev_afxdp_get_numa_id(const struct netdev *netdev) + static void + xsk_remove_xdp_program(uint32_t ifindex, int xdpmode) + { +- uint32_t flags; ++ uint32_t ret, flags, prog_id = 0; + + flags = XDP_FLAGS_UPDATE_IF_NOEXIST; + +@@ -578,6 +578,18 @@ xsk_remove_xdp_program(uint32_t ifindex, int xdpmode) + flags |= XDP_FLAGS_DRV_MODE; + } + ++ /* Check whether XDP program is loaded. */ ++ ret = bpf_get_link_xdp_id(ifindex, &prog_id, flags); ++ if (ret) { ++ VLOG_ERR("Failed to get XDP prog id (%s)", ovs_strerror(errno)); ++ return; ++ } ++ ++ if (!prog_id) { ++ VLOG_INFO("No XDP program is loaded at ifindex %d", ifindex); ++ return; ++ } ++ + bpf_set_link_xdp_fd(ifindex, -1, flags); + } + +-- +2.14.1 + + diff --git a/netdev-afxdp-Fix-umem-creation-failure-due-to-uninit.patch b/netdev-afxdp-Fix-umem-creation-failure-due-to-uninit.patch new file mode 100644 index 0000000..6820be7 --- /dev/null +++ b/netdev-afxdp-Fix-umem-creation-failure-due-to-uninit.patch @@ -0,0 +1,37 @@ +From e3d50e225545b6307aa7157fd5740bfdc040223e Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Wed, 9 Oct 2019 16:17:58 +0200 +Subject: netdev-afxdp: Fix umem creation failure due to uninitialized config. + +Later version of 'struct xsk_umem_config' contains additional field +'flags'. OVS doesn't use that field passing uninitialized stack +memory to the 'xsk_umem__create()' call that could fail with +'Invalid argument' if 'flags' are non-zero or, even worse, create +umem with unexpected properties. + +We need to clear the whole structure explicitly to avoid this kind +of issues. + +Fixes: 0de1b425962d ("netdev-afxdp: add new netdev type for AF_XDP.") +Signed-off-by: Ilya Maximets +Signed-off-by: William Tu +--- + lib/netdev-afxdp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c +index 6486c8233..47b4af59d 100644 +--- a/lib/netdev-afxdp.c ++++ b/lib/netdev-afxdp.c +@@ -168,6 +168,7 @@ xsk_configure_umem(void *buffer, uint64_t size, int xdpmode) + + umem = xzalloc(sizeof *umem); + ++ memset(&uconfig, 0, sizeof uconfig); + uconfig.fill_size = PROD_NUM_DESCS; + uconfig.comp_size = CONS_NUM_DESCS; + uconfig.frame_size = FRAME_SIZE; +-- +2.14.1 + + diff --git a/netdev-afxdp-Update-memory-locking-limits-unconditio.patch b/netdev-afxdp-Update-memory-locking-limits-unconditio.patch new file mode 100644 index 0000000..0c47e1b --- /dev/null +++ b/netdev-afxdp-Update-memory-locking-limits-unconditio.patch @@ -0,0 +1,59 @@ +From 069c80b47ff2fa4e7b4e455568c995e4fe8f3a18 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Wed, 9 Oct 2019 16:23:31 +0200 +Subject: netdev-afxdp: Update memory locking limits unconditionally. + +Any type of AF_XDP socket in all modes implies creation of BPF map of +type BPF_MAP_TYPE_XSKMAP. This leads to BPF_MAP_CREATE syscall and +subsequently 'xsk_map_alloc()' function that will charge required +memory from the memlock limit and fail with EPERM if we're trying +to allocate more. + +On my system with 64K bytes of max locked memory by default, OVS +frequently starts to fail after addition of 3rd afxdp port in SKB +mode: + + netdev_afxdp|ERR|xsk_socket__create failed (Operation not permitted) + mode: SKB qid: 0 + +Fixes: 0de1b425962d ("netdev-afxdp: add new netdev type for AF_XDP.") +Signed-off-by: Ilya Maximets +Signed-off-by: William Tu +--- + lib/netdev-afxdp.c | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c +index 47b4af59d..7b452c459 100644 +--- a/lib/netdev-afxdp.c ++++ b/lib/netdev-afxdp.c +@@ -536,19 +536,12 @@ netdev_afxdp_reconfigure(struct netdev *netdev) + netdev->n_rxq = dev->requested_n_rxq; + netdev->n_txq = netdev->n_rxq; + +- if (dev->requested_xdpmode == XDP_ZEROCOPY) { +- dev->xdpmode = XDP_ZEROCOPY; +- VLOG_INFO("AF_XDP device %s in DRV mode.", netdev_get_name(netdev)); +- if (setrlimit(RLIMIT_MEMLOCK, &r)) { +- VLOG_ERR("ERROR: setrlimit(RLIMIT_MEMLOCK): %s", +- ovs_strerror(errno)); +- } +- } else { +- dev->xdpmode = XDP_COPY; +- VLOG_INFO("AF_XDP device %s in SKB mode.", netdev_get_name(netdev)); +- /* TODO: set rlimit back to previous value +- * when no device is in DRV mode. +- */ ++ dev->xdpmode = dev->requested_xdpmode; ++ VLOG_INFO("%s: Setting XDP mode to %s.", netdev_get_name(netdev), ++ dev->xdpmode == XDP_ZEROCOPY ? "DRV" : "SKB"); ++ ++ if (setrlimit(RLIMIT_MEMLOCK, &r)) { ++ VLOG_ERR("setrlimit(RLIMIT_MEMLOCK) failed: %s", ovs_strerror(errno)); + } + + err = xsk_configure_all(netdev); +-- +2.14.1 + + diff --git a/netdev-dpdk-Fix-flow-control-not-configuring.patch b/netdev-dpdk-Fix-flow-control-not-configuring.patch new file mode 100644 index 0000000..0436cdb --- /dev/null +++ b/netdev-dpdk-Fix-flow-control-not-configuring.patch @@ -0,0 +1,76 @@ +From cb7e9a8240d6a46de831bf549abc6282a59d5edd Mon Sep 17 00:00:00 2001 +From: Tomasz Konieczny +Date: Thu, 12 Sep 2019 12:43:20 +0200 +Subject: netdev-dpdk: Fix flow control not configuring. + +Currently OVS is unable to change flow control configuration in DPDK +because new settings are being overwritten by current settings with +rte_eth_dev_flow_ctrl_get(). The fix restores correct order of +operations and at the same time does not trigger error on devices +without flow control support when flow control not requested. + +Fixes: 7e1de65e8dfb ("netdev-dpdk: Fix failure to configure flow control at netdev-init.") +Signed-off-by: Tomasz Konieczny +Co-authored-by: Ilya Maximets +Signed-off-by: Ilya Maximets +--- + lib/netdev-dpdk.c | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c +index 5466499b4..0bb826111 100644 +--- a/lib/netdev-dpdk.c ++++ b/lib/netdev-dpdk.c +@@ -1805,6 +1805,7 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, + { + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + bool rx_fc_en, tx_fc_en, autoneg, lsc_interrupt_mode; ++ bool flow_control_requested = true; + enum rte_eth_fc_mode fc_mode; + static const enum rte_eth_fc_mode fc_mode_set[2][2] = { + {RTE_FC_NONE, RTE_FC_TX_PAUSE}, +@@ -1892,15 +1893,34 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, + autoneg = smap_get_bool(args, "flow-ctrl-autoneg", false); + + fc_mode = fc_mode_set[tx_fc_en][rx_fc_en]; ++ ++ if (!smap_get(args, "rx-flow-ctrl") && !smap_get(args, "tx-flow-ctrl") ++ && !smap_get(args, "flow-ctrl-autoneg")) { ++ /* FIXME: User didn't ask for flow control configuration. ++ * For now we'll not print a warning if flow control is not ++ * supported by the DPDK port. */ ++ flow_control_requested = false; ++ } ++ ++ /* Get the Flow control configuration. */ ++ err = -rte_eth_dev_flow_ctrl_get(dev->port_id, &dev->fc_conf); ++ if (err) { ++ if (err == ENOTSUP) { ++ if (flow_control_requested) { ++ VLOG_WARN("%s: Flow control is not supported.", ++ netdev_get_name(netdev)); ++ } ++ err = 0; /* Not fatal. */ ++ } else { ++ VLOG_WARN("%s: Cannot get flow control parameters: %s", ++ netdev_get_name(netdev), rte_strerror(err)); ++ } ++ goto out; ++ } ++ + if (dev->fc_conf.mode != fc_mode || autoneg != dev->fc_conf.autoneg) { + dev->fc_conf.mode = fc_mode; + dev->fc_conf.autoneg = autoneg; +- /* Get the Flow control configuration for DPDK-ETH */ +- err = rte_eth_dev_flow_ctrl_get(dev->port_id, &dev->fc_conf); +- if (err) { +- VLOG_WARN("Cannot get flow control parameters on port " +- DPDK_PORT_ID_FMT", err=%d", dev->port_id, err); +- } + dpdk_eth_flow_ctrl_setup(dev); + } + +-- +2.14.1 + + diff --git a/netdev-dpdk-Fix-padding-info-comment.patch b/netdev-dpdk-Fix-padding-info-comment.patch new file mode 100644 index 0000000..8ea8942 --- /dev/null +++ b/netdev-dpdk-Fix-padding-info-comment.patch @@ -0,0 +1,44 @@ +From 0976ef00a5e5a1e79ce74f8bbb2e9243851c4c00 Mon Sep 17 00:00:00 2001 +From: Kevin Traynor +Date: Thu, 5 Sep 2019 14:21:09 +0100 +Subject: netdev-dpdk: Fix padding info comment. + +The comment was incorrectly updated. Fix it to the +correct value of 36 pad bytes. + +/* --- cacheline 5 boundary (320 bytes) --- */ +union { + struct { + struct netdev_stats stats; /* 320 336 */ + /* --- cacheline 5 boundary (320 bytes) was 16 bytes ago --- */ + uint64_t tx_retries; /* 656 8 */ + rte_spinlock_t stats_lock; /* 664 4 */ + }; /* 352 */ + uint8_t pad52[384]; /* 384 */ +}; /* 320 384 */ + +Fixes: c161357d5d96 ("netdev-dpdk: Add custom stat for vhost tx retries.") +Reported-by: Ilya Maximets +Signed-off-by: Kevin Traynor +Signed-off-by: Ian Stokes +--- + lib/netdev-dpdk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c +index 48057835f..5466499b4 100644 +--- a/lib/netdev-dpdk.c ++++ b/lib/netdev-dpdk.c +@@ -451,7 +451,7 @@ struct netdev_dpdk { + uint64_t tx_retries; + /* Protects stats */ + rte_spinlock_t stats_lock; +- /* 4 pad bytes here. */ ++ /* 36 pad bytes here. */ + ); + + PADDED_MEMBERS(CACHE_LINE_SIZE, +-- +2.14.1 + + diff --git a/ofproto-Fix-crash-on-PACKET_OUT-due-to-recursive-loc.patch b/ofproto-Fix-crash-on-PACKET_OUT-due-to-recursive-loc.patch new file mode 100644 index 0000000..afd934c --- /dev/null +++ b/ofproto-Fix-crash-on-PACKET_OUT-due-to-recursive-loc.patch @@ -0,0 +1,259 @@ +From 458e91300ee08abb6a3936f2549cc5d944c02107 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Fri, 1 Nov 2019 22:24:39 +0100 +Subject: ofproto: Fix crash on PACKET_OUT due to recursive locking after upcall. + +Handling of OpenFlow PACKET_OUT implies pushing the packet through +the datapath and packet processing inside the datapath could trigger +an upcall. In case of system datapath, 'dpif_execute()' sends packet +to the kernel module and returns. If any, upcall will be triggered +inside the kernel and handled by a separate thread in userspace. +But in case of userspace datapath full processing of the packet happens +inside the 'dpif_execute()' in the same thread that handled PACKET_OUT. +This causes an issue if upcall will lead to modification of flow rules. +For example, it could happen while processing of 'learn' actions. +Since whole handling of PACKET_OUT is protected by 'ofproto_mutex', +OVS will assert on attempt to take it recursively while processing +'learn' actions: + + 0 __GI_raise (sig=sig@entry=6) + 1 __GI_abort () + 2 ovs_abort_valist () + 3 ovs_abort () + 4 ovs_mutex_lock_at (where=where@entry=0xad4199 "ofproto/ofproto.c:5391") + + 5 ofproto_flow_mod_learn () at ofproto/ofproto.c:5391 + + 6 xlate_learn_action () at ofproto/ofproto-dpif-xlate.c:5378 + <'learn' action found> + 7 do_xlate_actions () at ofproto/ofproto-dpif-xlate.c:6893 + 8 xlate_recursively () at ofproto/ofproto-dpif-xlate.c:4233 + 9 xlate_table_action () at ofproto/ofproto-dpif-xlate.c:4361 + 10 in xlate_ofpact_resubmit () at ofproto/ofproto-dpif-xlate.c:4672 + 11 do_xlate_actions () at ofproto/ofproto-dpif-xlate.c:6773 + 12 xlate_actions () at ofproto/ofproto-dpif-xlate.c:7570 + + 13 upcall_xlate () at ofproto/ofproto-dpif-upcall.c:1197 + 14 process_upcall () at ofproto/ofproto-dpif-upcall.c:1413 + 15 upcall_cb () at ofproto/ofproto-dpif-upcall.c:1315 + 16 dp_netdev_upcall (DPIF_UC_MISS) at lib/dpif-netdev.c:6236 + + 17 handle_packet_upcall () at lib/dpif-netdev.c:6591 + 18 fast_path_processing () at lib/dpif-netdev.c:6709 + 19 dp_netdev_input__ () at lib/dpif-netdev.c:6797 + 20 dp_netdev_recirculate () at lib/dpif-netdev.c:6842 + 21 dp_execute_cb () at lib/dpif-netdev.c:7158 + 22 odp_execute_actions () at lib/odp-execute.c:794 + 23 dp_netdev_execute_actions () at lib/dpif-netdev.c:7332 + 24 dpif_netdev_execute () at lib/dpif-netdev.c:3725 + 25 dpif_netdev_operate () at lib/dpif-netdev.c:3756 + + 26 dpif_operate () at lib/dpif.c:1367 + 27 dpif_execute () at lib/dpif.c:1321 + 28 packet_execute () at ofproto/ofproto-dpif.c:4760 + 29 ofproto_packet_out_finish () at ofproto/ofproto.c:3594 + + 30 handle_packet_out () at ofproto/ofproto.c:3635 + 31 handle_single_part_openflow (OFPTYPE_PACKET_OUT) at ofproto/ofproto.c:8400 + 32 handle_openflow () at ofproto/ofproto.c:8587 + 33 ofconn_run () + 34 connmgr_run () + 35 ofproto_run () + 36 bridge_run__ () + 37 bridge_run () + 38 main () + +Fix that by splitting the 'ofproto_packet_out_finish()' in two parts. +First one that translates side-effects and requires holding 'ofproto_mutex' +and the second that only pushes packet to datapath. The second part moved +out of 'ofproto_mutex' because 'ofproto_mutex' is not required and actually +should not be taken in order to avoid recursive locking. + +Reported-by: Anil Kumar Koli +Reported-at: https://mail.openvswitch.org/pipermail/ovs-discuss/2019-April/048494.html +Signed-off-by: Ilya Maximets +Acked-by: Ben Pfaff +--- + ofproto/ofproto-dpif.c | 40 ++++++++++++++++++++++++++++++---------- + ofproto/ofproto-provider.h | 12 +++++++++--- + ofproto/ofproto.c | 29 +++++++++++++++++++++++++---- + 3 files changed, 64 insertions(+), 17 deletions(-) + +diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c +index c7c70062c..3d6d72a40 100644 +--- a/ofproto/ofproto-dpif.c ++++ b/ofproto/ofproto-dpif.c +@@ -4786,12 +4786,13 @@ ofproto_dpif_xcache_execute(struct ofproto_dpif *ofproto, + } + + static void +-packet_execute(struct ofproto *ofproto_, struct ofproto_packet_out *opo) ++packet_execute_prepare(struct ofproto *ofproto_, ++ struct ofproto_packet_out *opo) + OVS_REQUIRES(ofproto_mutex) + { + struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); + struct dpif_flow_stats stats; +- struct dpif_execute execute; ++ struct dpif_execute *execute; + + struct ofproto_dpif_packet_out *aux = opo->aux; + ovs_assert(aux); +@@ -4800,22 +4801,40 @@ packet_execute(struct ofproto *ofproto_, struct ofproto_packet_out *opo) + dpif_flow_stats_extract(opo->flow, opo->packet, time_msec(), &stats); + ofproto_dpif_xcache_execute(ofproto, &aux->xcache, &stats); + +- execute.actions = aux->odp_actions.data; +- execute.actions_len = aux->odp_actions.size; ++ execute = xzalloc(sizeof *execute); ++ execute->actions = xmemdup(aux->odp_actions.data, aux->odp_actions.size); ++ execute->actions_len = aux->odp_actions.size; + + pkt_metadata_from_flow(&opo->packet->md, opo->flow); +- execute.packet = opo->packet; +- execute.flow = opo->flow; +- execute.needs_help = aux->needs_help; +- execute.probe = false; +- execute.mtu = 0; ++ execute->packet = opo->packet; ++ execute->flow = opo->flow; ++ execute->needs_help = aux->needs_help; ++ execute->probe = false; ++ execute->mtu = 0; + + /* Fix up in_port. */ + ofproto_dpif_set_packet_odp_port(ofproto, opo->flow->in_port.ofp_port, + opo->packet); + +- dpif_execute(ofproto->backer->dpif, &execute); + ofproto_dpif_packet_out_delete(aux); ++ opo->aux = execute; ++} ++ ++static void ++packet_execute(struct ofproto *ofproto_, struct ofproto_packet_out *opo) ++ OVS_EXCLUDED(ofproto_mutex) ++{ ++ struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); ++ struct dpif_execute *execute = opo->aux; ++ ++ if (!execute) { ++ return; ++ } ++ ++ dpif_execute(ofproto->backer->dpif, execute); ++ ++ free(CONST_CAST(struct nlattr *, execute->actions)); ++ free(execute); + opo->aux = NULL; + } + +@@ -6194,6 +6213,7 @@ const struct ofproto_class ofproto_dpif_class = { + rule_get_stats, + packet_xlate, + packet_xlate_revert, ++ packet_execute_prepare, + packet_execute, + set_frag_handling, + nxt_resume, +diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h +index 7907d4bfb..d520a6380 100644 +--- a/ofproto/ofproto-provider.h ++++ b/ofproto/ofproto-provider.h +@@ -1368,9 +1368,15 @@ struct ofproto_class { + * packet_xlate_revert() calls have to be made in reverse order. */ + void (*packet_xlate_revert)(struct ofproto *, struct ofproto_packet_out *); + +- /* Executes the datapath actions, translation side-effects, and stats as +- * produced by ->packet_xlate(). The caller retains ownership of 'opo'. +- */ ++ /* Translates side-effects, and stats as produced by ->packet_xlate(). ++ * Prepares to execute datapath actions. The caller retains ownership ++ * of 'opo'. */ ++ void (*packet_execute_prepare)(struct ofproto *, ++ struct ofproto_packet_out *opo); ++ ++ /* Executes the datapath actions. The caller retains ownership of 'opo'. ++ * Should be called after successful packet_execute_prepare(). ++ * No-op if called after packet_xlate_revert(). */ + void (*packet_execute)(struct ofproto *, struct ofproto_packet_out *opo); + + /* Changes the OpenFlow IP fragment handling policy to 'frag_handling', +diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c +index 6ffaced18..715da0607 100644 +--- a/ofproto/ofproto.c ++++ b/ofproto/ofproto.c +@@ -3589,10 +3589,21 @@ ofproto_packet_out_revert(struct ofproto *ofproto, + ofproto->ofproto_class->packet_xlate_revert(ofproto, opo); + } + ++static void ++ofproto_packet_out_prepare(struct ofproto *ofproto, ++ struct ofproto_packet_out *opo) ++ OVS_REQUIRES(ofproto_mutex) ++{ ++ ofproto->ofproto_class->packet_execute_prepare(ofproto, opo); ++} ++ ++/* Execution of packet_out action in datapath could end up in upcall with ++ * subsequent flow translations and possible rule modifications. ++ * So, the caller should not hold 'ofproto_mutex'. */ + static void + ofproto_packet_out_finish(struct ofproto *ofproto, + struct ofproto_packet_out *opo) +- OVS_REQUIRES(ofproto_mutex) ++ OVS_EXCLUDED(ofproto_mutex) + { + ofproto->ofproto_class->packet_execute(ofproto, opo); + } +@@ -3635,10 +3646,13 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) + opo.version = p->tables_version; + error = ofproto_packet_out_start(p, &opo); + if (!error) { +- ofproto_packet_out_finish(p, &opo); ++ ofproto_packet_out_prepare(p, &opo); + } + ovs_mutex_unlock(&ofproto_mutex); + ++ if (!error) { ++ ofproto_packet_out_finish(p, &opo); ++ } + ofproto_packet_out_uninit(&opo); + return error; + } +@@ -8157,7 +8171,7 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) + } else if (be->type == OFPTYPE_GROUP_MOD) { + ofproto_group_mod_finish(ofproto, &be->ogm, &req); + } else if (be->type == OFPTYPE_PACKET_OUT) { +- ofproto_packet_out_finish(ofproto, &be->opo); ++ ofproto_packet_out_prepare(ofproto, &be->opo); + } + } + if (error) { +@@ -8168,7 +8182,7 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) + /* Send error referring to the original message. */ + ofconn_send_error(ofconn, be->msg, error); + error = OFPERR_OFPBFC_MSG_FAILED; +- ++ + /* Revert. Undo all the changes made above. */ + LIST_FOR_EACH_REVERSE_CONTINUE (be, node, &bundle->msg_list) { + if (be->type == OFPTYPE_FLOW_MOD) { +@@ -8187,6 +8201,13 @@ do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags) + ovs_mutex_unlock(&ofproto_mutex); + } + ++ /* Executing remaining datapath actions. */ ++ LIST_FOR_EACH (be, node, &bundle->msg_list) { ++ if (be->type == OFPTYPE_PACKET_OUT) { ++ ofproto_packet_out_finish(ofproto, &be->opo); ++ } ++ } ++ + /* The bundle is discarded regardless the outcome. */ + ofp_bundle_remove__(ofconn, bundle); + return error; +-- +2.14.1 + + diff --git a/ofproto-dpif-Allow-IPv6-ND-Extensions-only-if-suppor.patch b/ofproto-dpif-Allow-IPv6-ND-Extensions-only-if-suppor.patch new file mode 100644 index 0000000..70ad720 --- /dev/null +++ b/ofproto-dpif-Allow-IPv6-ND-Extensions-only-if-suppor.patch @@ -0,0 +1,180 @@ +From df5db2a7a0fe9a4b6f5eafaada20a9b834aebbac Mon Sep 17 00:00:00 2001 +From: Flavio Leitner +Date: Wed, 20 Nov 2019 11:21:13 -0300 +Subject: ofproto-dpif: Allow IPv6 ND Extensions only if supported + +The IPv6 ND Extensions is only implemented in userspace datapath, +but nothing prevents that to be used with other datapaths. + +This patch probes the datapath and only allows if the support +is available. + +Fixes: 9b2b84973 ("Support for match & set ICMPv6 reserved and options type fields") +Acked-by: Eelco Chaudron +Acked-by: Aaron Conole +Signed-off-by: Flavio Leitner +Signed-off-by: Ben Pfaff +--- + lib/odp-util.c | 17 ++++++++------- + lib/odp-util.h | 6 ++++- + ofproto/ofproto-dpif.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++- + tests/test-odp.c | 1 + + 4 files changed, 73 insertions(+), 10 deletions(-) + +diff --git a/lib/odp-util.c b/lib/odp-util.c +index 84ea4c148..df06f8026 100644 +--- a/lib/odp-util.c ++++ b/lib/odp-util.c +@@ -6180,23 +6180,24 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, + && (!export_mask || (data->tp_src == htons(0xff) + && data->tp_dst == htons(0xff)))) { + struct ovs_key_nd *nd_key; +- struct ovs_key_nd_extensions *nd_ext_key; + nd_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ND, + sizeof *nd_key); + nd_key->nd_target = data->nd_target; + nd_key->nd_sll = data->arp_sha; + nd_key->nd_tll = data->arp_tha; + +- /* Add ND Extensions Attr only if reserved field ++ /* Add ND Extensions Attr only if supported and reserved field + * or options type is set. */ +- if (data->igmp_group_ip4 != 0 || +- data->tcp_flags != 0) { +- nd_ext_key = +- nl_msg_put_unspec_uninit(buf, ++ if (parms->support.nd_ext) { ++ struct ovs_key_nd_extensions *nd_ext_key; ++ ++ if (data->igmp_group_ip4 != 0 || data->tcp_flags != 0) { ++ nd_ext_key = nl_msg_put_unspec_uninit(buf, + OVS_KEY_ATTR_ND_EXTENSIONS, + sizeof *nd_ext_key); +- nd_ext_key->nd_reserved = data->igmp_group_ip4; +- nd_ext_key->nd_options_type = ntohs(data->tcp_flags); ++ nd_ext_key->nd_reserved = data->igmp_group_ip4; ++ nd_ext_key->nd_options_type = ntohs(data->tcp_flags); ++ } + } + } + } +diff --git a/lib/odp-util.h b/lib/odp-util.h +index a03e82532..f15e258e6 100644 +--- a/lib/odp-util.h ++++ b/lib/odp-util.h +@@ -203,7 +203,11 @@ int odp_flow_from_string(const char *s, const struct simap *port_names, + \ + /* Conntrack original direction tuple matching * supported. */ \ + ODP_SUPPORT_FIELD(bool, ct_orig_tuple, "CT orig tuple") \ +- ODP_SUPPORT_FIELD(bool, ct_orig_tuple6, "CT orig tuple for IPv6") ++ ODP_SUPPORT_FIELD(bool, ct_orig_tuple6, "CT orig tuple for IPv6") \ ++ \ ++ /* If true, it means that the datapath supports the IPv6 Neigh \ ++ * Discovery Extension bits. */ \ ++ ODP_SUPPORT_FIELD(bool, nd_ext, "IPv6 ND Extension") + + /* Indicates support for various fields. This defines how flows will be + * serialised. */ +diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c +index a8c7369d0..c7c70062c 100644 +--- a/ofproto/ofproto-dpif.c ++++ b/ofproto/ofproto-dpif.c +@@ -1377,6 +1377,55 @@ check_max_dp_hash_alg(struct dpif_backer *backer) + return max_alg; + } + ++/* Tests whether 'backer''s datapath supports IPv6 ND extensions. ++ * Only userspace datapath support OVS_KEY_ATTR_ND_EXTENSIONS in keys. ++ * ++ * Returns false if 'backer' definitely does not support matching and ++ * setting reserved and options type, true if it seems to support. */ ++static bool ++check_nd_extensions(struct dpif_backer *backer) ++{ ++ struct eth_header *eth; ++ struct ofpbuf actions; ++ struct dpif_execute execute; ++ struct dp_packet packet; ++ struct flow flow; ++ int error; ++ struct ovs_key_nd_extensions key, mask; ++ ++ ofpbuf_init(&actions, 64); ++ memset(&key, 0x53, sizeof key); ++ memset(&mask, 0x7f, sizeof mask); ++ commit_masked_set_action(&actions, OVS_KEY_ATTR_ND_EXTENSIONS, &key, &mask, ++ sizeof key); ++ ++ /* Compose a dummy ethernet packet. */ ++ dp_packet_init(&packet, ETH_HEADER_LEN); ++ eth = dp_packet_put_zeros(&packet, ETH_HEADER_LEN); ++ eth->eth_type = htons(0x1234); ++ ++ flow_extract(&packet, &flow); ++ ++ /* Execute the actions. On datapaths without support fails with EINVAL. */ ++ execute.actions = actions.data; ++ execute.actions_len = actions.size; ++ execute.packet = &packet; ++ execute.flow = &flow; ++ execute.needs_help = false; ++ execute.probe = true; ++ execute.mtu = 0; ++ ++ error = dpif_execute(backer->dpif, &execute); ++ ++ dp_packet_uninit(&packet); ++ ofpbuf_uninit(&actions); ++ ++ VLOG_INFO("%s: Datapath %s IPv6 ND Extensions", dpif_name(backer->dpif), ++ error ? "does not support" : "supports"); ++ ++ return !error; ++} ++ + #define CHECK_FEATURE__(NAME, SUPPORT, FIELD, VALUE, ETHTYPE) \ + static bool \ + check_##NAME(struct dpif_backer *backer) \ +@@ -1447,10 +1496,10 @@ check_support(struct dpif_backer *backer) + backer->rt_support.odp.ct_zone = check_ct_zone(backer); + backer->rt_support.odp.ct_mark = check_ct_mark(backer); + backer->rt_support.odp.ct_label = check_ct_label(backer); +- + backer->rt_support.odp.ct_state_nat = check_ct_state_nat(backer); + backer->rt_support.odp.ct_orig_tuple = check_ct_orig_tuple(backer); + backer->rt_support.odp.ct_orig_tuple6 = check_ct_orig_tuple6(backer); ++ backer->rt_support.odp.nd_ext = check_nd_extensions(backer); + } + + static int +@@ -4453,6 +4502,14 @@ check_actions(const struct ofproto_dpif *ofproto, + "ct original direction tuple"); + return OFPERR_NXBAC_CT_DATAPATH_SUPPORT; + } ++ } else if (!support->nd_ext && ofpact->type == OFPACT_SET_FIELD) { ++ const struct mf_field *dst = ofpact_get_mf_dst(ofpact); ++ ++ if (dst->id == MFF_ND_RESERVED || dst->id == MFF_ND_OPTIONS_TYPE) { ++ report_unsupported_act("set field", ++ "setting IPv6 ND Extensions fields"); ++ return OFPERR_OFPBAC_BAD_SET_ARGUMENT; ++ } + } + } + +diff --git a/tests/test-odp.c b/tests/test-odp.c +index 09fec706a..0ddfd4070 100644 +--- a/tests/test-odp.c ++++ b/tests/test-odp.c +@@ -65,6 +65,7 @@ parse_keys(bool wc_keys) + .ct_mark = true, + .ct_label = true, + .max_vlan_headers = SIZE_MAX, ++ .nd_ext = true, + }, + }; + +-- +2.14.1 + + diff --git a/ofproto-dpif-Free-leaked-webster.patch b/ofproto-dpif-Free-leaked-webster.patch new file mode 100644 index 0000000..9dd0326 --- /dev/null +++ b/ofproto-dpif-Free-leaked-webster.patch @@ -0,0 +1,53 @@ +From d49777c9d7f1241bb38687ece237eb4135285ce9 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:34 -0700 +Subject: ofproto-dpif: Free leaked 'webster' + +Valgrind reported: + +1122: ofproto-dpif - select group with explicit dp_hash selection method + +==16884== 64 bytes in 1 blocks are definitely lost in loss record 320 of 346 +==16884== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==16884== by 0x532512: xcalloc (util.c:121) +==16884== by 0x4262B9: group_setup_dp_hash_table (ofproto-dpif.c:4846) +==16884== by 0x4267CB: group_set_selection_method (ofproto-dpif.c:4938) +==16884== by 0x4267CB: group_construct (ofproto-dpif.c:4984) +==16884== by 0x417250: init_group (ofproto.c:7286) +==16884== by 0x41B4FC: add_group_start (ofproto.c:7316) +==16884== by 0x42247A: ofproto_group_mod_start (ofproto.c:7589) +==16884== by 0x4250EC: handle_group_mod (ofproto.c:7744) +==16884== by 0x4250EC: handle_single_part_openflow (ofproto.c:8428) +==16884== by 0x4250EC: handle_openflow (ofproto.c:8606) +==16884== by 0x4579E2: ofconn_run (connmgr.c:1318) +==16884== by 0x4579E2: connmgr_run (connmgr.c:355) +==16884== by 0x41E0F5: ofproto_run (ofproto.c:1845) +==16884== by 0x40BA63: bridge_run__ (bridge.c:2971) +==16884== by 0x410CF3: bridge_run (bridge.c:3029) +==16884== by 0x407614: main (ovs-vswitchd.c:127) + +This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + ofproto/ofproto-dpif.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c +index 46fa13571..7bb0f7bdb 100644 +--- a/ofproto/ofproto-dpif.c ++++ b/ofproto/ofproto-dpif.c +@@ -4871,6 +4871,7 @@ group_setup_dp_hash_table(struct group_dpif *group, size_t max_hash) + if (n_hash > MAX_SELECT_GROUP_HASH_VALUES || + (max_hash != 0 && n_hash > max_hash)) { + VLOG_DBG(" Too many hash values required: %"PRIu64, n_hash); ++ free(webster); + return false; + } + +-- +2.14.1 + + diff --git a/ofproto-dpif-Uninitialize-xlate_cache-to-free-resour.patch b/ofproto-dpif-Uninitialize-xlate_cache-to-free-resour.patch new file mode 100644 index 0000000..4cc0e51 --- /dev/null +++ b/ofproto-dpif-Uninitialize-xlate_cache-to-free-resour.patch @@ -0,0 +1,49 @@ +From f1afa83349efb7622d986574211f3bd24d16e642 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:28 -0700 +Subject: ofproto-dpif: Uninitialize 'xlate_cache' to free resources + +Valgrind reported: + +1210: ofproto-dpif - continuation after clone + +==32205== 4,392 (1,440 direct, 2,952 indirect) bytes in 12 blocks are definitely lost in loss record 359 of 362 +==32205== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==32205== by 0x532574: xmalloc (util.c:138) +==32205== by 0x4F98CA: ofpbuf_init (ofpbuf.c:123) +==32205== by 0x42C07B: nxt_resume (ofproto-dpif.c:5110) +==32205== by 0x41796F: handle_nxt_resume (ofproto.c:3677) +==32205== by 0x424583: handle_single_part_openflow (ofproto.c:8473) +==32205== by 0x424583: handle_openflow (ofproto.c:8606) +==32205== by 0x4579E2: ofconn_run (connmgr.c:1318) +==32205== by 0x4579E2: connmgr_run (connmgr.c:355) +==32205== by 0x41E0F5: ofproto_run (ofproto.c:1845) +==32205== by 0x40BA63: bridge_run__ (bridge.c:2971) +==32205== by 0x410CF3: bridge_run (bridge.c:3029) +==32205== by 0x407614: main (ovs-vswitchd.c:127) + +This is because 'xcache' was not destroyed properly. This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + ofproto/ofproto-dpif.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c +index 751535249..46fa13571 100644 +--- a/ofproto/ofproto-dpif.c ++++ b/ofproto/ofproto-dpif.c +@@ -5148,6 +5148,7 @@ nxt_resume(struct ofproto *ofproto_, + /* Clean up. */ + ofpbuf_uninit(&odp_actions); + dp_packet_uninit(&packet); ++ xlate_cache_uninit(&xcache); + + return error; + } +-- +2.14.1 + + diff --git a/ofproto-dpif-xlate-Restore-table-ID-on-error-in-xlat.patch b/ofproto-dpif-xlate-Restore-table-ID-on-error-in-xlat.patch new file mode 100644 index 0000000..4ad1df1 --- /dev/null +++ b/ofproto-dpif-xlate-Restore-table-ID-on-error-in-xlat.patch @@ -0,0 +1,29 @@ +From 8cdf840f1af1c6da0459cb3a056c122762cd7fd6 Mon Sep 17 00:00:00 2001 +From: Ben Pfaff +Date: Mon, 14 Oct 2019 15:34:21 -0700 +Subject: ofproto-dpif-xlate: Restore table ID on error in xlate_table_action(). + +Found by inspection. + +Acked-by: Yi-Hung Wei +Signed-off-by: Ben Pfaff +--- + ofproto/ofproto-dpif-xlate.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c +index 0dc43d17a..09096ed6f 100644 +--- a/ofproto/ofproto-dpif-xlate.c ++++ b/ofproto/ofproto-dpif-xlate.c +@@ -4331,6 +4331,7 @@ xlate_table_action(struct xlate_ctx *ctx, ofp_port_t in_port, uint8_t table_id, + !is_ip_any(&ctx->xin->flow)) { + xlate_report_error(ctx, + "resubmit(ct) with non-tracked or non-IP packet!"); ++ ctx->table_id = old_table_id; + return; + } + tuple_swap(&ctx->xin->flow, ctx->wc); +-- +2.14.1 + + diff --git a/ofproto-fix-a-typo-for-ttl-in-dpif_sflow_actions.patch b/ofproto-fix-a-typo-for-ttl-in-dpif_sflow_actions.patch new file mode 100644 index 0000000..ceafcf4 --- /dev/null +++ b/ofproto-fix-a-typo-for-ttl-in-dpif_sflow_actions.patch @@ -0,0 +1,28 @@ +From 58bc4f3b43ff959bec4a6d1293465ec75c7d6bb5 Mon Sep 17 00:00:00 2001 +From: Martin Zhang +Date: Mon, 7 Oct 2019 00:34:55 -0400 +Subject: ofproto: fix a typo for ttl in dpif_sflow_actions + +Signed-off-by: Martin Zhang +Signed-off-by: Ben Pfaff +--- + ofproto/ofproto-dpif-sflow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c +index 03bd763c6..9abaab61b 100644 +--- a/ofproto/ofproto-dpif-sflow.c ++++ b/ofproto/ofproto-dpif-sflow.c +@@ -1026,7 +1026,7 @@ sflow_read_set_action(const struct nlattr *attr, + sflow_actions->tunnel.ip_tos = key->ipv4_tos; + } + if (key->ipv4_ttl) { +- sflow_actions->tunnel.ip_tos = key->ipv4_ttl; ++ sflow_actions->tunnel.ip_ttl = key->ipv4_ttl; + } + } + break; +-- +2.14.1 + + diff --git a/ofproto-fix-stack-buffer-overflow.patch b/ofproto-fix-stack-buffer-overflow.patch new file mode 100644 index 0000000..0a7523d --- /dev/null +++ b/ofproto-fix-stack-buffer-overflow.patch @@ -0,0 +1,102 @@ +From e4d2627cf5fcecdc64c1bacc2917ecdbcf00cf70 Mon Sep 17 00:00:00 2001 +From: Linhaifeng +Date: Fri, 29 Nov 2019 06:13:35 +0000 +Subject: ofproto: fix stack-buffer-overflow + +Should use flow->actions not &flow->actions. + +here is ASAN report: +================================================================= +==57189==ERROR: AddressSanitizer: stack-buffer-overflow on address 0xffff428fa0e8 at pc 0xffff7f61a520 bp 0xffff428f9420 sp 0xffff428f9498 READ of size 196 at 0xffff428fa0e8 thread T150 (revalidator22) + #0 0xffff7f61a51f in __interceptor_memcpy (/lib64/libasan.so.4+0xa251f) + #1 0xaaaad26a3b2b in ofpbuf_put lib/ofpbuf.c:426 + #2 0xaaaad26a30cb in ofpbuf_clone_data_with_headroom lib/ofpbuf.c:248 + #3 0xaaaad26a2e77 in ofpbuf_clone_with_headroom lib/ofpbuf.c:218 + #4 0xaaaad26a2dc3 in ofpbuf_clone lib/ofpbuf.c:208 + #5 0xaaaad23e3993 in ukey_set_actions ofproto/ofproto-dpif-upcall.c:1640 + #6 0xaaaad23e3f03 in ukey_create__ ofproto/ofproto-dpif-upcall.c:1696 + #7 0xaaaad23e553f in ukey_create_from_dpif_flow ofproto/ofproto-dpif-upcall.c:1806 + #8 0xaaaad23e65fb in ukey_acquire ofproto/ofproto-dpif-upcall.c:1984 + #9 0xaaaad23eb583 in revalidate ofproto/ofproto-dpif-upcall.c:2625 + #10 0xaaaad23dee5f in udpif_revalidator ofproto/ofproto-dpif-upcall.c:1076 + #11 0xaaaad26b84ef in ovsthread_wrapper lib/ovs-thread.c:708 + #12 0xffff7e74a8bb in start_thread (/lib64/libpthread.so.0+0x78bb) + #13 0xffff7e0665cb in thread_start (/lib64/libc.so.6+0xd55cb) + +Address 0xffff428fa0e8 is located in stack of thread T150 (revalidator22) at offset 328 in frame + #0 0xaaaad23e4cab in ukey_create_from_dpif_flow ofproto/ofproto-dpif-upcall.c:1762 + + This frame has 4 object(s): + [32, 96) 'actions' + [128, 192) 'buf' + [224, 328) 'full_flow' + [384, 2432) 'stub' <== Memory access at offset 328 partially underflows this variable +HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext + (longjmp and C++ exceptions *are* supported) Thread T150 (revalidator22) created by T0 here: + #0 0xffff7f5b0f7f in __interceptor_pthread_create (/lib64/libasan.so.4+0x38f7f) + #1 0xaaaad26b891f in ovs_thread_create lib/ovs-thread.c:792 + #2 0xaaaad23dc62f in udpif_start_threads ofproto/ofproto-dpif-upcall.c:639 + #3 0xaaaad23daf87 in ofproto_set_flow_table ofproto/ofproto-dpif-upcall.c:446 + #4 0xaaaad230ff7f in dpdk_evs_cfg_set vswitchd/bridge.c:1134 + #5 0xaaaad2310097 in bridge_reconfigure vswitchd/bridge.c:1148 + #6 0xaaaad23279d7 in bridge_run vswitchd/bridge.c:3944 + #7 0xaaaad23365a3 in main vswitchd/ovs-vswitchd.c:240 + #8 0xffff7dfb1adf in __libc_start_main (/lib64/libc.so.6+0x20adf) + #9 0xaaaad230a3d3 (/usr/sbin/ovs-vswitchd-2.7.0-1.1.RC5.001.asan+0x26f3d3) + +SUMMARY: AddressSanitizer: stack-buffer-overflow (/lib64/libasan.so.4+0xa251f) in __interceptor_memcpy Shadow bytes around the buggy address: + 0x200fe851f3c0: 00 00 00 00 f1 f1 f1 f1 f8 f2 f2 f2 00 00 00 00 + 0x200fe851f3d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x200fe851f3e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x200fe851f3f0: 00 00 00 00 f1 f1 f1 f1 00 00 00 00 00 00 00 00 + 0x200fe851f400: f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 +=>0x200fe851f410: 00 00 00 00 00 00 00 00 00 00 00 00 00[f2]f2 f2 + 0x200fe851f420: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 + 0x200fe851f430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x200fe851f440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x200fe851f450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 0x200fe851f460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): + Addressable: 00 + Partially addressable: 01 02 03 04 05 06 07 + Heap left redzone: fa + Freed heap region: fd + Stack left redzone: f1 + Stack mid redzone: f2 + Stack right redzone: f3 + Stack after return: f5 + Stack use after scope: f8 + Global redzone: f9 + Global init order: f6 + Poisoned by user: f7 + Container overflow: fc + Array cookie: ac + Intra object redzone: bb + ASan internal: fe + Left alloca redzone: ca + Right alloca redzone: cb +==57189==ABORTING + +Acked-by: Numan Siddique +Signed-off-by: Linhaifeng +Signed-off-by: Ben Pfaff +--- + ofproto/ofproto-dpif-upcall.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c +index f46cdf213..0237f9451 100644 +--- a/ofproto/ofproto-dpif-upcall.c ++++ b/ofproto/ofproto-dpif-upcall.c +@@ -1798,7 +1798,7 @@ ukey_create_from_dpif_flow(const struct udpif *udpif, + } + + reval_seq = seq_read(udpif->reval_seq) - 1; /* Ensure revalidation. */ +- ofpbuf_use_const(&actions, &flow->actions, flow->actions_len); ++ ofpbuf_use_const(&actions, flow->actions, flow->actions_len); + *ukey = ukey_create__(flow->key, flow->key_len, + flow->mask, flow->mask_len, flow->ufid_present, + &flow->ufid, flow->pmd_id, &actions, +-- +2.14.1 + + diff --git a/openvswitch-kmod.spec b/openvswitch-kmod.spec index d1154e4..d572a56 100644 --- a/openvswitch-kmod.spec +++ b/openvswitch-kmod.spec @@ -19,6 +19,73 @@ Summary: Open vSwitch Kernel Modules License: GPLv2 URL: http://www.openvswitch.org/ Source: openvswitch-%{version}.tar.gz +Patch0: Prepare-for-2.12.1.patch +Patch1: faq-Update-list-of-kernels-supported-by-2.12.patch +Patch2: raft-Free-leaked-json-data.patch +Patch3: ofproto-dpif-Uninitialize-xlate_cache-to-free-resour.patch +Patch4: dpif-netdev-Handle-uninitialized-value-error-for-mat.patch +Patch5: ovs-ofctl-Free-leaked-minimatch.patch +Patch6: trigger-Free-leaked-ovsdb_schema.patch +Patch7: ovsdb-client-Free-ovsdb_schema.patch +Patch8: dns-resolve-Free-struct-ub_result-when-callback-retu.patch +Patch9: ofproto-dpif-Free-leaked-webster.patch +Patch10: db-ctl-base-Free-leaked-ovsdb_datum.patch +Patch11: conntrack-Validate-accessing-of-conntrack-data-in-pk.patch +Patch12: faq-Update-OVS-DPDK-version-table-for-OVS-2.12.patch +Patch13: datapath-compat-Backports-bugfixes-for-nf_conncount.patch +Patch14: stream_ssl-fix-important-memory-leak-in-ssl_connect-.patch +Patch15: Documentation-Fix-security-mailing-list-address.patch +Patch16: conntrack-Fix-check_orig_tuple-Valgrind-false-positi.patch +Patch17: conntrack-Fix-reverse_nat_packet-variable-datatype.patch +Patch18: ovn-Exclude-inport-and-outport-symbol-tables-from-co.patch +Patch19: flow-fix-incorrect-padding-length-checking-in-ipv6_s.patch +Patch20: netdev-dpdk-Fix-padding-info-comment.patch +Patch21: travis-Drop-MD-related-workaround-for-sparse.patch +Patch22: doc-Fix-incorrect-reference-for-dpdk-testpmd.patch +Patch23: ofproto-fix-a-typo-for-ttl-in-dpif_sflow_actions.patch +Patch24: flow-Fix-using-pointer-to-member-of-packed-struct-ic.patch +Patch25: netdev-afxdp-Fix-umem-creation-failure-due-to-uninit.patch +Patch26: netdev-afxdp-Update-memory-locking-limits-unconditio.patch +Patch27: dpif-netlink-Free-leaked-nl_sock.patch +Patch28: ovsdb-server-Don-t-drop-all-connections-on-read-writ.patch +Patch29: tc-Limit-the-max-action-number-to-16.patch +Patch30: lldp-Fix-for-OVS-crashes-when-a-LLDP-enabled-port-is.patch +Patch31: tests-Fix-indentation-in-userspace-packet-type-aware.patch +Patch32: flow-Fix-crash-on-vlan-packets-with-partial-offloadi.patch +Patch33: ovsdb-server-fix-memory-leak-while-converting-databa.patch +Patch34: dpif-netdev-Do-not-mix-recirculation-depth-into-RSS-.patch +Patch35: dpif-netdev-Fix-time-delta-overflow-in-case-of-race-.patch +Patch36: rhel-openvswitch-fedora.spec.in-Fix-output-redirect-.patch +Patch37: lflow.c-Fix-memory-leak-of-lflow_ref_list_node-ref_n.patch +Patch38: Avoid-indeterminate-statistics-in-offload-implementa.patch +Patch39: lib-tc-Fix-flow-dump-for-tunnel-id-equal-zero.patch +Patch40: netdev-dpdk-Fix-flow-control-not-configuring.patch +Patch41: vswitch.xml-Fix-column-for-xdpmode.patch +Patch42: compat-Add-compat-fix-for-old-kernels.patch +Patch43: rhel-Fix-ovs-kmod-manage.sh-that-may-create-invalid-.patch +Patch44: ovsdb-server-fix-memory-leak-while-deleting-zone.patch +Patch45: ovn-Prevent-erroneous-duplicate-IP-address-messages.patch +Patch46: jsonrpc-increase-input-buffer-size-from-512-to-4096.patch +Patch47: ovsdb-raft-Fix-election-timer-parsing-in-snapshot-RP.patch +Patch48: ipf-bail-out-when-ipf-state-is-COMPLETED.patch +Patch49: ofproto-dpif-Allow-IPv6-ND-Extensions-only-if-suppor.patch +Patch50: flow-Fix-IPv6-header-parser-with-partial-offloading.patch +Patch51: ofproto-Fix-crash-on-PACKET_OUT-due-to-recursive-loc.patch +Patch52: dpdk-Use-DPDK-18.11.5-release.patch +Patch53: dp-packet-Fix-clearing-copying-of-memory-layout-flag.patch +Patch54: rhel-Support-RHEL7.7-build-and-packaging.patch +Patch55: ofproto-fix-stack-buffer-overflow.patch +Patch56: sparse-Get-rid-of-obsolete-rte_flow-header.patch +Patch57: ofproto-dpif-xlate-Restore-table-ID-on-error-in-xlat.patch +Patch58: ovn-controller-Add-missing-port-group-lflow-referenc.patch +Patch59: cirrus-Use-latest-stable-FreeBSD-images.patch +Patch60: cirrus-Use-FreeBSD-12.1-stable-release.patch +Patch61: rhel-Support-RHEL-7.8-kernel-module-rpm-build.patch +Patch62: dpif-netdev-Avoid-infinite-re-addition-of-misconfigu.patch +Patch63: netdev-afxdp-Avoid-removing-of-XDP-program-if-not-lo.patch +Patch64: system-afxdp.at-Add-test-for-infinite-re-addition-of.patch +Patch65: ovsdb-cluster.at-Wait-until-leader-is-elected-before.patch +Patch66: ovsdb-raft-Fix-the-problem-when-cluster-restarted-af.patch #Source1: openvswitch-init Buildroot: /tmp/openvswitch-xen-rpm @@ -37,6 +104,7 @@ Open vSwitch Linux kernel module %prep %setup -q -n openvswitch-%{version} +%autopatch -p1 %build sh boot.sh @@ -90,26 +158,31 @@ else [ -d "/lib/modules/$k/kernel/" ] && /sbin/depmod -a "$k" done if [ -x "/sbin/weak-modules" ]; then - rpm -ql kmod-%{oname} | grep '\.ko$' | \ - /sbin/weak-modules --add-modules + for m in openvswitch vport-gre vport-stt vport-geneve \ + vport-lisp vport-vxlan; do + echo "/lib/modules/%{kernel}/extra/openvswitch/$m.ko" + done | /sbin/weak-modules --add-modules fi fi %postun if [ "$1" = 0 ]; then # Erase, not upgrade for kname in `ls -d /lib/modules/*` -do - rm -rf $kname/weak-updates/openvswitch -done + do + rm -rf $kname/weak-updates/openvswitch + done fi /sbin/depmod -a %files %defattr(0644,root,root) -/lib/modules/ +/lib/modules/*/extra/openvswitch/*.ko +%exclude /lib/modules/*/modules.* /etc/depmod.d/kmod-openvswitch.conf %attr(755,root,root) /usr/share/openvswitch/scripts/ovs-kmod-manage.sh %changelog +* Sat Dec 21 2019 openEuler Buildteam - 2.12.0 +- Add opensource patch * Fri Nov 22 2019 openEuler Buildteam - 2.12.0 - First build diff --git a/ovn-Exclude-inport-and-outport-symbol-tables-from-co.patch b/ovn-Exclude-inport-and-outport-symbol-tables-from-co.patch new file mode 100644 index 0000000..f8792da --- /dev/null +++ b/ovn-Exclude-inport-and-outport-symbol-tables-from-co.patch @@ -0,0 +1,124 @@ +From 1f82d15cb88333520c367365cf76a7b97bd18e16 Mon Sep 17 00:00:00 2001 +From: Numan Siddique +Date: Sat, 14 Sep 2019 13:19:17 +0530 +Subject: ovn: Exclude inport and outport symbol tables from conjunction + +If there are multiple ACLs associated with a port group and they +match on a range of some field, then ovn-controller doesn't install +the flows properly and this results in broken ACL functionality. + +For example, if there is a port group - pg1 with logical ports - [p1, p2] +and if there are below ACLs (only match condition is shown) + +1 - outport == @pg1 && ip4 && tcp.dst >= 500 && tcp.dst <= 501 +2 - outport == @pg1 && ip4 && tcp.dst >= 600 && tcp.dst <= 601 + +The first ACL will result in the below OF flows + +1. conj_id=1,tcp +2. tcp,reg15=0x11: conjunction(1, 1/2) +3. tcp,reg15=0x12: conjunction(1, 1/2) +5. tcp,tp_dst=500: conjunction(1, 2/2) +6. tcp,tp_dst=501: conjunction(1, 2/2) + +The second ACL will result in the below OF flows +7. conj_id=2,tcp +8. tcp,reg15=0x11: conjunction(2, 1/2) +9. tcp,reg15=0x12: conjunction(2, 1/2) +11. tcp,tp_dst=600: conjunction(2, 2/2) +12. tcp,tp_dst=601: conjunction(2, 3/2) + +The OF flows (2) and (8) have the exact match but with different action. +This results in only one of the flows getting installed. The same goes +for the flows (3) and (9). And this completely breaks the ACL functionality +for such scenarios. + +In order to fix this issue, this patch excludes the 'inport' and 'outport' symbols +from conjunction. With this patch we will have the below flows. + +tcp,reg15=0x11,tp_dst=500 +tcp,reg15=0x11,tp_dst=501 +tcp,reg15=0x12,tp_dst=500 +tcp,reg15=0x12,tp_dst=501 +tcp,reg15=0x13,tp_dst=500 +tcp,reg15=0x13,tp_dst=501 +tcp,reg15=0x11,tp_dst=600 +tcp,reg15=0x11,tp_dst=601 +tcp,reg15=0x12,tp_dst=600 +tcp,reg15=0x12,tp_dst=601 +tcp,reg15=0x13,tp_dst=600 +tcp,reg15=0x13,tp_dst=601 + +Acked-by: Mark Michelson +Acked-by: Daniel Alvarez +Signed-off-by: Numan Siddique + +(cherry-picked from ovn commit 298701dbc99645700be41680a43d049cb061847a) + +Signed-off-by: Ben Pfaff +--- + ovn/lib/expr.c | 2 +- + tests/ovn.at | 26 ++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+), 1 deletion(-) + +diff --git a/ovn/lib/expr.c b/ovn/lib/expr.c +index e4c650f7c..c0871e1e8 100644 +--- a/ovn/lib/expr.c ++++ b/ovn/lib/expr.c +@@ -1499,7 +1499,7 @@ expr_symtab_add_string(struct shash *symtab, const char *name, + const struct mf_field *field = mf_from_id(id); + struct expr_symbol *symbol; + +- symbol = add_symbol(symtab, name, 0, prereqs, EXPR_L_NOMINAL, false, ++ symbol = add_symbol(symtab, name, 0, prereqs, EXPR_L_NOMINAL, true, + field->writable); + symbol->field = field; + return symbol; +diff --git a/tests/ovn.at b/tests/ovn.at +index 2361524ff..54aa19bb2 100644 +--- a/tests/ovn.at ++++ b/tests/ovn.at +@@ -573,6 +573,24 @@ ip,reg14=0x6 + ipv6,reg14=0x5 + ipv6,reg14=0x6 + ]) ++AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip4 && tcp && tcp.dst == {500, 501}'], [0], [dnl ++tcp,reg14=0x5,tp_dst=500 ++tcp,reg14=0x5,tp_dst=501 ++tcp,reg14=0x6,tp_dst=500 ++tcp,reg14=0x6,tp_dst=501 ++]) ++AT_CHECK([expr_to_flow 'outport == {"eth0", "eth1", "eth2"} && ip4 && tcp && tcp.src == {400, 401} && tcp.dst == {500, 501}'], [0], [dnl ++conj_id=1,tcp,reg15=0x5 ++conj_id=2,tcp,reg15=0x6 ++tcp,reg15=0x5,tp_dst=500: conjunction(1, 0/2) ++tcp,reg15=0x5,tp_dst=501: conjunction(1, 0/2) ++tcp,reg15=0x5,tp_src=400: conjunction(1, 1/2) ++tcp,reg15=0x5,tp_src=401: conjunction(1, 1/2) ++tcp,reg15=0x6,tp_dst=500: conjunction(2, 0/2) ++tcp,reg15=0x6,tp_dst=501: conjunction(2, 0/2) ++tcp,reg15=0x6,tp_src=400: conjunction(2, 1/2) ++tcp,reg15=0x6,tp_src=401: conjunction(2, 1/2) ++]) + AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl + (no flows) + ]) +@@ -677,6 +695,14 @@ reg15=0x11 + reg15=0x12 + reg15=0x13 + ]) ++AT_CHECK([expr_to_flow 'outport == @pg1 && ip4.src == {10.0.0.4, 10.0.0.5}'], [0], [dnl ++ip,reg15=0x11,nw_src=10.0.0.4 ++ip,reg15=0x11,nw_src=10.0.0.5 ++ip,reg15=0x12,nw_src=10.0.0.4 ++ip,reg15=0x12,nw_src=10.0.0.5 ++ip,reg15=0x13,nw_src=10.0.0.4 ++ip,reg15=0x13,nw_src=10.0.0.5 ++]) + AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl + (no flows) + ]) +-- +2.14.1 + + diff --git a/ovn-Prevent-erroneous-duplicate-IP-address-messages.patch b/ovn-Prevent-erroneous-duplicate-IP-address-messages.patch new file mode 100644 index 0000000..7bed821 --- /dev/null +++ b/ovn-Prevent-erroneous-duplicate-IP-address-messages.patch @@ -0,0 +1,54 @@ +From 30227d3b6f82381c3bf0ffa6e988a0799c0682f4 Mon Sep 17 00:00:00 2001 +From: Mark Michelson +Date: Tue, 12 Nov 2019 11:59:31 -0500 +Subject: ovn: Prevent erroneous duplicate IP address messages. + +This is a backport to OVS 2.12 of OVN master commit 21c29d5b0c. + +When using dynamic address assignment for logical switches, OVN reserves +the first address in the subnet for the attached router port to use. + +In commit 488d153ee87841c042af05bc0eb8b5481aaa98cf, the IPAM code was +modified to add assigned router port addresses to IPAM. The use case for +this was when a switch was joined to multiple routers, and all router +addresses were dynamically assigned. + +However, that commit also made it so that when a router rightly claimed +the first address in the subnet, ovn-northd would issue a warning about +a duplicate IP address being set. This change fixes the issue by adding +a special case so that we don't add the router's IP address to IPAM if +it is the first address in the subnet. This prevents the warning message +from appearing. + +Signed-off-by: Mark Michelson +Acked-by: Numan Siddique +Acked-by: Han ZHou +Signed-off-by: Ben Pfaff +--- + ovn/northd/ovn-northd.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c +index 6c6de2afd..1c9164924 100644 +--- a/ovn/northd/ovn-northd.c ++++ b/ovn/northd/ovn-northd.c +@@ -1194,7 +1194,14 @@ ipam_add_port_addresses(struct ovn_datapath *od, struct ovn_port *op) + + for (size_t i = 0; i < lrp_networks.n_ipv4_addrs; i++) { + uint32_t ip = ntohl(lrp_networks.ipv4_addrs[i].addr); +- ipam_insert_ip(op->peer->od, ip); ++ /* If the router has the first IP address of the subnet, don't add ++ * it to IPAM. We already added this when we initialized IPAM for ++ * the datapath. This will just result in an erroneous message ++ * about a duplicate IP address. ++ */ ++ if (ip != op->peer->od->ipam_info.start_ipv4) { ++ ipam_insert_ip(op->peer->od, ip); ++ } + } + + destroy_lport_addresses(&lrp_networks); +-- +2.14.1 + + diff --git a/ovn-controller-Add-missing-port-group-lflow-referenc.patch b/ovn-controller-Add-missing-port-group-lflow-referenc.patch new file mode 100644 index 0000000..8cecb09 --- /dev/null +++ b/ovn-controller-Add-missing-port-group-lflow-referenc.patch @@ -0,0 +1,234 @@ +From fc7fcb604c863b8eafaa319658e11da6d31e3fb6 Mon Sep 17 00:00:00 2001 +From: Dumitru Ceara +Date: Tue, 3 Dec 2019 10:56:54 +0100 +Subject: ovn-controller: Add missing port group lflow references. + +The commit that adds incremental processing for port-group changes +doesn't store logical flow references for port groups. If a port group +is updated (e.g., a port is added) no logical flow recalculation will be +performed. + +To fix this, when parsing the flow expression also store the referenced +port groups and bind them to the logical flows that depend on them. If +the port group is updated then the logical flows referring them will +also be reinstalled. + +(cherry picked from ovn commit bbcac48d443e98cbe47d3941f7e192c9c3443cb5) + +Reported-by: Daniel Alvarez +Reported-at: https://bugzilla.redhat.com/1778164 +CC: Han Zhou +Fixes: 978f5e90af0a ("ovn-controller: Incremental processing for port-group changes.") +Tested-By: Daniel Alvarez +Signed-off-by: Dumitru Ceara +Signed-off-by: Han Zhou +Signed-off-by: Ben Pfaff +--- + include/ovn/expr.h | 4 +++- + ovn/controller/lflow.c | 9 ++++++++- + ovn/lib/actions.c | 4 ++-- + ovn/lib/expr.c | 24 +++++++++++++++++------- + ovn/utilities/ovn-trace.c | 2 +- + tests/test-ovn.c | 8 ++++---- + 6 files changed, 35 insertions(+), 16 deletions(-) + +diff --git a/include/ovn/expr.h b/include/ovn/expr.h +index 22f633e57..21bf51c22 100644 +--- a/include/ovn/expr.h ++++ b/include/ovn/expr.h +@@ -390,11 +390,13 @@ void expr_print(const struct expr *); + struct expr *expr_parse(struct lexer *, const struct shash *symtab, + const struct shash *addr_sets, + const struct shash *port_groups, +- struct sset *addr_sets_ref); ++ struct sset *addr_sets_ref, ++ struct sset *port_groups_ref); + struct expr *expr_parse_string(const char *, const struct shash *symtab, + const struct shash *addr_sets, + const struct shash *port_groups, + struct sset *addr_sets_ref, ++ struct sset *port_groups_ref, + char **errorp); + + struct expr *expr_clone(struct expr *); +diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c +index dd72a5b46..047b4711c 100644 +--- a/ovn/controller/lflow.c ++++ b/ovn/controller/lflow.c +@@ -616,14 +616,21 @@ consider_logical_flow( + struct expr *expr; + + struct sset addr_sets_ref = SSET_INITIALIZER(&addr_sets_ref); ++ struct sset port_groups_ref = SSET_INITIALIZER(&port_groups_ref); + expr = expr_parse_string(lflow->match, &symtab, addr_sets, port_groups, +- &addr_sets_ref, &error); ++ &addr_sets_ref, &port_groups_ref, &error); + const char *addr_set_name; + SSET_FOR_EACH (addr_set_name, &addr_sets_ref) { + lflow_resource_add(lfrr, REF_TYPE_ADDRSET, addr_set_name, + &lflow->header_.uuid); + } ++ const char *port_group_name; ++ SSET_FOR_EACH (port_group_name, &port_groups_ref) { ++ lflow_resource_add(lfrr, REF_TYPE_PORTGROUP, port_group_name, ++ &lflow->header_.uuid); ++ } + sset_destroy(&addr_sets_ref); ++ sset_destroy(&port_groups_ref); + + if (!error) { + if (prereqs) { +diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c +index 274297194..58e0006d9 100644 +--- a/ovn/lib/actions.c ++++ b/ovn/lib/actions.c +@@ -240,8 +240,8 @@ add_prerequisite(struct action_context *ctx, const char *prerequisite) + struct expr *expr; + char *error; + +- expr = expr_parse_string(prerequisite, ctx->pp->symtab, NULL, NULL, NULL, +- &error); ++ expr = expr_parse_string(prerequisite, ctx->pp->symtab, NULL, NULL, ++ NULL, NULL, &error); + ovs_assert(!error); + ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, expr); + } +diff --git a/ovn/lib/expr.c b/ovn/lib/expr.c +index c0871e1e8..629187a5b 100644 +--- a/ovn/lib/expr.c ++++ b/ovn/lib/expr.c +@@ -467,7 +467,8 @@ struct expr_context { + const struct shash *symtab; /* Symbol table. */ + const struct shash *addr_sets; /* Address set table. */ + const struct shash *port_groups; /* Port group table. */ +- struct sset *addr_sets_ref; /* The set of address set referenced. */ ++ struct sset *addr_sets_ref; /* The set of address set referenced. */ ++ struct sset *port_groups_ref; /* The set of port groups referenced. */ + bool not; /* True inside odd number of NOT operators. */ + unsigned int paren_depth; /* Depth of nested parentheses. */ + }; +@@ -769,6 +770,10 @@ static bool + parse_port_group(struct expr_context *ctx, struct expr_constant_set *cs, + size_t *allocated_values) + { ++ if (ctx->port_groups_ref) { ++ sset_add(ctx->port_groups_ref, ctx->lexer->token.s); ++ } ++ + struct expr_constant_set *port_group + = (ctx->port_groups + ? shash_find_data(ctx->port_groups, ctx->lexer->token.s) +@@ -1283,13 +1288,15 @@ struct expr * + expr_parse(struct lexer *lexer, const struct shash *symtab, + const struct shash *addr_sets, + const struct shash *port_groups, +- struct sset *addr_sets_ref) ++ struct sset *addr_sets_ref, ++ struct sset *port_groups_ref) + { + struct expr_context ctx = { .lexer = lexer, + .symtab = symtab, + .addr_sets = addr_sets, + .port_groups = port_groups, +- .addr_sets_ref = addr_sets_ref }; ++ .addr_sets_ref = addr_sets_ref, ++ .port_groups_ref = port_groups_ref }; + return lexer->error ? NULL : expr_parse__(&ctx); + } + +@@ -1304,6 +1311,7 @@ expr_parse_string(const char *s, const struct shash *symtab, + const struct shash *addr_sets, + const struct shash *port_groups, + struct sset *addr_sets_ref, ++ struct sset *port_groups_ref, + char **errorp) + { + struct lexer lexer; +@@ -1311,7 +1319,7 @@ expr_parse_string(const char *s, const struct shash *symtab, + lexer_init(&lexer, s); + lexer_get(&lexer); + struct expr *expr = expr_parse(&lexer, symtab, addr_sets, port_groups, +- addr_sets_ref); ++ addr_sets_ref, port_groups_ref); + lexer_force_end(&lexer); + *errorp = lexer_steal_error(&lexer); + if (*errorp) { +@@ -1537,7 +1545,8 @@ expr_get_level(const struct expr *expr) + static enum expr_level + expr_parse_level(const char *s, const struct shash *symtab, char **errorp) + { +- struct expr *expr = expr_parse_string(s, symtab, NULL, NULL, NULL, errorp); ++ struct expr *expr = expr_parse_string(s, symtab, NULL, NULL, NULL, NULL, ++ errorp); + enum expr_level level = expr ? expr_get_level(expr) : EXPR_L_NOMINAL; + expr_destroy(expr); + return level; +@@ -1708,7 +1717,7 @@ parse_and_annotate(const char *s, const struct shash *symtab, + char *error; + struct expr *expr; + +- expr = expr_parse_string(s, symtab, NULL, NULL, NULL, &error); ++ expr = expr_parse_string(s, symtab, NULL, NULL, NULL, NULL, &error); + if (expr) { + expr = expr_annotate_(expr, symtab, nesting, &error); + } +@@ -3432,7 +3441,8 @@ expr_parse_microflow(const char *s, const struct shash *symtab, + lexer_init(&lexer, s); + lexer_get(&lexer); + +- struct expr *e = expr_parse(&lexer, symtab, addr_sets, port_groups, NULL); ++ struct expr *e = expr_parse(&lexer, symtab, addr_sets, port_groups, ++ NULL, NULL); + lexer_force_end(&lexer); + + if (e) { +diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c +index b532b8eaf..9c27131be 100644 +--- a/ovn/utilities/ovn-trace.c ++++ b/ovn/utilities/ovn-trace.c +@@ -850,7 +850,7 @@ read_flows(void) + char *error; + struct expr *match; + match = expr_parse_string(sblf->match, &symtab, &address_sets, +- &port_groups, NULL, &error); ++ &port_groups, NULL, NULL, &error); + if (error) { + VLOG_WARN("%s: parsing expression failed (%s)", + sblf->match, error); +diff --git a/tests/test-ovn.c b/tests/test-ovn.c +index cf1bc5432..6b5e365f0 100644 +--- a/tests/test-ovn.c ++++ b/tests/test-ovn.c +@@ -289,7 +289,7 @@ test_parse_expr__(int steps) + char *error; + + expr = expr_parse_string(ds_cstr(&input), &symtab, &addr_sets, +- &port_groups, NULL, &error); ++ &port_groups, NULL, NULL, &error); + if (!error && steps > 0) { + expr = expr_annotate(expr, &symtab, &error); + } +@@ -413,8 +413,8 @@ test_evaluate_expr(struct ovs_cmdl_context *ctx) + while (!ds_get_test_line(&input, stdin)) { + struct expr *expr; + +- expr = expr_parse_string(ds_cstr(&input), &symtab, NULL, NULL, NULL, +- &error); ++ expr = expr_parse_string(ds_cstr(&input), &symtab, NULL, NULL, ++ NULL, NULL, &error); + if (!error) { + expr = expr_annotate(expr, &symtab, &error); + } +@@ -889,7 +889,7 @@ test_tree_shape_exhaustively(struct expr *expr, struct shash *symtab, + + char *error; + modified = expr_parse_string(ds_cstr(&s), symtab, NULL, +- NULL, NULL, &error); ++ NULL, NULL, NULL, &error); + if (error) { + fprintf(stderr, "%s fails to parse (%s)\n", + ds_cstr(&s), error); +-- +2.14.1 + + diff --git a/ovs-ofctl-Free-leaked-minimatch.patch b/ovs-ofctl-Free-leaked-minimatch.patch new file mode 100644 index 0000000..f8ac729 --- /dev/null +++ b/ovs-ofctl-Free-leaked-minimatch.patch @@ -0,0 +1,47 @@ +From 430c292030ffda57f122c282d3eb165a97412b91 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:30 -0700 +Subject: ovs-ofctl: Free leaked minimatch + +Valgrind reported: + +1056: ofproto - bundle with multiple flow mods (OpenFlow 1.4) + +==19220== 160 bytes in 2 blocks are definitely lost in loss record 24 of 34 +==19220== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==19220== by 0x4979A4: xmalloc (util.c:138) +==19220== by 0x42407D: miniflow_alloc (flow.c:3340) +==19220== by 0x4296CF: minimatch_init (match.c:1758) +==19220== by 0x46273D: parse_ofp_str__ (ofp-flow.c:1759) +==19220== by 0x465B9E: parse_ofp_str (ofp-flow.c:1790) +==19220== by 0x465CE0: parse_ofp_flow_mod_str (ofp-flow.c:1817) +==19220== by 0x465DF6: parse_ofp_flow_mod_file (ofp-flow.c:1876) +==19220== by 0x410BA3: ofctl_flow_mod_file.isra.19 (ovs-ofctl.c:1773) +==19220== by 0x417933: ovs_cmdl_run_command__ (command-line.c:223) +==19220== by 0x406F68: main (ovs-ofctl.c:179) + +This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + utilities/ovs-ofctl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c +index 754629d3d..06289d296 100644 +--- a/utilities/ovs-ofctl.c ++++ b/utilities/ovs-ofctl.c +@@ -1724,6 +1724,7 @@ bundle_flow_mod__(const char *remote, struct ofputil_flow_mod *fms, + + ovs_list_push_back(&requests, &request->list_node); + free(CONST_CAST(struct ofpact *, fm->ofpacts)); ++ minimatch_destroy(&fm->match); + } + + bundle_transact(vconn, &requests, OFPBF_ORDERED | OFPBF_ATOMIC); +-- +2.14.1 + + diff --git a/ovsdb-client-Free-ovsdb_schema.patch b/ovsdb-client-Free-ovsdb_schema.patch new file mode 100644 index 0000000..5a666da --- /dev/null +++ b/ovsdb-client-Free-ovsdb_schema.patch @@ -0,0 +1,43 @@ +From f66cb2ec1538330c69f94ea4af252868a3aeb8d4 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:32 -0700 +Subject: ovsdb-client: Free ovsdb_schema + +Valgrind reported: + +1925: schema conversion online - standalone + +==10727== 689 (56 direct, 633 indirect) bytes in 1 blocks are definitely lost in loss record 64 of 66 +==10727== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==10727== by 0x449D42: xcalloc (util.c:121) +==10727== by 0x40F45C: ovsdb_schema_create (ovsdb.c:41) +==10727== by 0x40F7F8: ovsdb_schema_from_json (ovsdb.c:217) +==10727== by 0x40FB4E: ovsdb_schema_from_file (ovsdb.c:101) +==10727== by 0x40B156: do_convert (ovsdb-client.c:1639) +==10727== by 0x4061C6: main (ovsdb-client.c:282) + +This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + ovsdb/ovsdb-client.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c +index 9ae15e557..bfc90e6f7 100644 +--- a/ovsdb/ovsdb-client.c ++++ b/ovsdb/ovsdb-client.c +@@ -1654,6 +1654,7 @@ do_convert(struct jsonrpc *rpc, const char *database_ OVS_UNUSED, + ovsdb_schema_to_json(new_schema)), NULL); + check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply); + jsonrpc_msg_destroy(reply); ++ ovsdb_schema_destroy(new_schema); + } + + static void +-- +2.14.1 + + diff --git a/ovsdb-cluster.at-Wait-until-leader-is-elected-before.patch b/ovsdb-cluster.at-Wait-until-leader-is-elected-before.patch new file mode 100644 index 0000000..7006d37 --- /dev/null +++ b/ovsdb-cluster.at-Wait-until-leader-is-elected-before.patch @@ -0,0 +1,59 @@ +From 9f301dc92a45206edaeb9cf0f3a9d7e01c32499a Mon Sep 17 00:00:00 2001 +From: Han Zhou +Date: Tue, 3 Dec 2019 17:57:19 -0800 +Subject: ovsdb-cluster.at: Wait until leader is elected before DB compact. + +In test case "election timer change", before testing DB compact, +we had to insert some data. Otherwise, inserting data after DB +compact will cause busy loop as mentioned in the XXX comment. + +The root cause of the busy loop is still not clear, but the test +itself didn't wait until the leader election finish before initiating +DB compact. This patch adds the wait to make sure the test continue +after leader is elected so that the following tests are based on +a clean state. While this wait is added, the busy loop problem is +gone even without inserting the data, so the additional data insertion +is also removed by this patch. + +A separate patch will address the busy loop problem in the scenario: +1. Restart cluster +2. DB compact before the cluster is ready +3. Insert data + +Signed-off-by: Han Zhou +Signed-off-by: Ben Pfaff +--- + tests/ovsdb-cluster.at | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/tests/ovsdb-cluster.at b/tests/ovsdb-cluster.at +index 70812a787..ef4ec205a 100644 +--- a/tests/ovsdb-cluster.at ++++ b/tests/ovsdb-cluster.at +@@ -233,17 +233,14 @@ done + OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s1 cluster/status $schema_name | grep "Election timer: 4000"]) + OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s2 cluster/status $schema_name | grep "Election timer: 4000"]) + ++# Wait until cluster is ready ++for i in `seq $n`; do ++ OVS_WAIT_WHILE([ovs-appctl -t "`pwd`"/s$i cluster/status $schema_name | grep "Leader: unknown"]) ++done ++ + # Latest timer should be restored after DB compact and restart. + # This is to test the install_snapshot RPC. + +-# XXX: Insert data before compact, because otherwise transaction will trigger +-# busy loop after compact. +-# poll_loop|DBG|wakeup due to 0-ms timeout at ../ovsdb/trigger.c:164 (89% CPU usage) +-AT_CHECK([ovsdb-client transact unix:s1.ovsdb '[["idltest", +- {"op": "insert", +- "table": "simple", +- "row": {"i": 1}}]]'], [0], [ignore], [ignore]) +- + # Compact online + for i in `seq $n`; do + AT_CHECK([ovs-appctl -t "`pwd`"/s$i ovsdb-server/compact]) +-- +2.14.1 + + diff --git a/ovsdb-raft-Fix-election-timer-parsing-in-snapshot-RP.patch b/ovsdb-raft-Fix-election-timer-parsing-in-snapshot-RP.patch new file mode 100644 index 0000000..1b9e981 --- /dev/null +++ b/ovsdb-raft-Fix-election-timer-parsing-in-snapshot-RP.patch @@ -0,0 +1,133 @@ +From 0f0cde9132141f2980a542e54dae02887972c162 Mon Sep 17 00:00:00 2001 +From: Han Zhou +Date: Wed, 13 Nov 2019 09:33:59 -0800 +Subject: ovsdb raft: Fix election timer parsing in snapshot RPC. + +Commit a76ba825 took care of saving and restoring election timer in +file header snapshot, but it didn't handle the parsing of election +timer in install_snapshot_request/reply RPC, which results in problems, +e.g. when election timer change log is compacted in snapshot and then a +new node join the cluster, the new node will use the default timer +instead of the new value. This patch fixed it by parsing election +timer in snapshot RPC. + +At the same time the patch updates the test case to cover the DB compact and +join senario. The test reveals another 2 problems related to clustered DB +compact, as commented in the test case's XXX, which need to be addressed +separately. + +Signed-off-by: Han Zhou +Signed-off-by: Ben Pfaff +--- + ovsdb/raft-rpc.c | 5 +++++ + ovsdb/raft.c | 2 +- + tests/ovsdb-cluster.at | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 55 insertions(+), 1 deletion(-) + +diff --git a/ovsdb/raft-rpc.c b/ovsdb/raft-rpc.c +index 56c07d487..18c83fe9c 100644 +--- a/ovsdb/raft-rpc.c ++++ b/ovsdb/raft-rpc.c +@@ -511,6 +511,7 @@ raft_install_snapshot_request_to_jsonrpc( + json_object_put(args, "last_servers", json_clone(rq->last_servers)); + json_object_put_format(args, "last_eid", + UUID_FMT, UUID_ARGS(&rq->last_eid)); ++ raft_put_uint64(args, "election_timer", rq->election_timer); + + json_object_put(args, "data", json_clone(rq->data)); + } +@@ -527,6 +528,9 @@ raft_install_snapshot_request_from_jsonrpc( + rq->last_index = raft_parse_required_uint64(p, "last_index"); + rq->last_term = raft_parse_required_uint64(p, "last_term"); + rq->last_eid = raft_parse_required_uuid(p, "last_eid"); ++ /* election_timer is optional in file header, but is always populated in ++ * install_snapshot_request. */ ++ rq->election_timer = raft_parse_required_uint64(p, "election_timer"); + + rq->data = json_nullable_clone( + ovsdb_parser_member(p, "data", OP_OBJECT | OP_ARRAY)); +@@ -541,6 +545,7 @@ raft_format_install_snapshot_request( + ds_put_format(s, " last_term=%"PRIu64, rq->last_term); + ds_put_format(s, " last_eid="UUID_FMT, UUID_ARGS(&rq->last_eid)); + ds_put_cstr(s, " last_servers="); ++ ds_put_format(s, " election_timer=%"PRIu64, rq->election_timer); + + struct hmap servers; + struct ovsdb_error *error = +diff --git a/ovsdb/raft.c b/ovsdb/raft.c +index a45c7f8ba..f354d50a5 100644 +--- a/ovsdb/raft.c ++++ b/ovsdb/raft.c +@@ -3257,7 +3257,7 @@ raft_send_install_snapshot_request(struct raft *raft, + .last_servers = raft->snap.servers, + .last_eid = raft->snap.eid, + .data = raft->snap.data, +- .election_timer = raft->election_timer, ++ .election_timer = raft->election_timer, /* use latest value */ + } + }; + raft_send(raft, &rpc); +diff --git a/tests/ovsdb-cluster.at b/tests/ovsdb-cluster.at +index de4295a7e..70812a787 100644 +--- a/tests/ovsdb-cluster.at ++++ b/tests/ovsdb-cluster.at +@@ -233,6 +233,55 @@ done + OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s1 cluster/status $schema_name | grep "Election timer: 4000"]) + OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s2 cluster/status $schema_name | grep "Election timer: 4000"]) + ++# Latest timer should be restored after DB compact and restart. ++# This is to test the install_snapshot RPC. ++ ++# XXX: Insert data before compact, because otherwise transaction will trigger ++# busy loop after compact. ++# poll_loop|DBG|wakeup due to 0-ms timeout at ../ovsdb/trigger.c:164 (89% CPU usage) ++AT_CHECK([ovsdb-client transact unix:s1.ovsdb '[["idltest", ++ {"op": "insert", ++ "table": "simple", ++ "row": {"i": 1}}]]'], [0], [ignore], [ignore]) ++ ++# Compact online ++for i in `seq $n`; do ++ AT_CHECK([ovs-appctl -t "`pwd`"/s$i ovsdb-server/compact]) ++done ++ ++# XXX: Insert data after compact, because otherwise vote will fail after ++# cluster restart after compact. There will be error logs like: ++# raft|ERR|internal error: deferred vote_request message completed but not ready to send because message index 9 is past last synced index 0: s2 vote_request: term=6 last_log_index=9 last_log_term=4 ++AT_CHECK([ovsdb-client transact unix:s1.ovsdb '[["idltest", ++ {"op": "insert", ++ "table": "simple", ++ "row": {"i": 1}}]]'], [0], [ignore], [ignore]) ++ ++for i in `seq $n`; do ++ printf "\ns$i: stopping\n" ++ OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid]) ++done ++for i in `seq $n`; do ++ AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db]) ++done ++for i in `seq $n`; do ++ OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s$i cluster/status $schema_name | grep "Election timer: 4000"]) ++done ++ ++# Wait until cluster is ready ++for i in `seq $n`; do ++ OVS_WAIT_WHILE([ovs-appctl -t "`pwd`"/s$i cluster/status $schema_name | grep "Leader: unknown"]) ++done ++ ++# Newly joined member should use latest timer value ++AT_CHECK([ovsdb-tool join-cluster s4.db $schema_name unix:s4.raft unix:s1.raft]) ++AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s4.log --pidfile=s4.pid --unixctl=s4 --remote=punix:s4.ovsdb s4.db]) ++OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s4 cluster/status $schema_name | grep "Election timer: 4000"]) ++# for i in `seq 10`; do ++# ovs-appctl -t "`pwd`"/s4 cluster/status $schema_name ++# sleep 1 ++# done ++ + AT_CLEANUP + + +-- +2.14.1 + + diff --git a/ovsdb-raft-Fix-the-problem-when-cluster-restarted-af.patch b/ovsdb-raft-Fix-the-problem-when-cluster-restarted-af.patch new file mode 100644 index 0000000..39827e4 --- /dev/null +++ b/ovsdb-raft-Fix-the-problem-when-cluster-restarted-af.patch @@ -0,0 +1,60 @@ +From 62b3f430c29799ee4ef09b058105883939e06d37 Mon Sep 17 00:00:00 2001 +From: Han Zhou +Date: Tue, 3 Dec 2019 17:57:20 -0800 +Subject: ovsdb raft: Fix the problem when cluster restarted after DB compaction. + +Cluster doesn't work after all nodes restarted after DB compaction, +unless there is any transaction after DB compaction before the restart. + +Error log is like: +raft|ERR|internal error: deferred vote_request message completed but not ready +to send because message index 9 is past last synced index 0: s2 vote_request: +term=6 last_log_index=9 last_log_term=4 + +The root cause is that the log_synced member is not initialized when +reading the raft header. This patch fixes it and remove the XXX +from the test case. + +Signed-off-by: Han Zhou +Signed-off-by: Ben Pfaff +--- + ovsdb/raft.c | 2 +- + tests/ovsdb-cluster.at | 8 -------- + 2 files changed, 1 insertion(+), 9 deletions(-) + +diff --git a/ovsdb/raft.c b/ovsdb/raft.c +index f354d50a5..4789bc4f2 100644 +--- a/ovsdb/raft.c ++++ b/ovsdb/raft.c +@@ -849,7 +849,7 @@ raft_read_header(struct raft *raft) + } else { + raft_entry_clone(&raft->snap, &h.snap); + raft->log_start = raft->log_end = h.snap_index + 1; +- raft->commit_index = h.snap_index; ++ raft->log_synced = raft->commit_index = h.snap_index; + raft->last_applied = h.snap_index - 1; + } + +diff --git a/tests/ovsdb-cluster.at b/tests/ovsdb-cluster.at +index ef4ec205a..15f821be6 100644 +--- a/tests/ovsdb-cluster.at ++++ b/tests/ovsdb-cluster.at +@@ -246,14 +246,6 @@ for i in `seq $n`; do + AT_CHECK([ovs-appctl -t "`pwd`"/s$i ovsdb-server/compact]) + done + +-# XXX: Insert data after compact, because otherwise vote will fail after +-# cluster restart after compact. There will be error logs like: +-# raft|ERR|internal error: deferred vote_request message completed but not ready to send because message index 9 is past last synced index 0: s2 vote_request: term=6 last_log_index=9 last_log_term=4 +-AT_CHECK([ovsdb-client transact unix:s1.ovsdb '[["idltest", +- {"op": "insert", +- "table": "simple", +- "row": {"i": 1}}]]'], [0], [ignore], [ignore]) +- + for i in `seq $n`; do + printf "\ns$i: stopping\n" + OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid]) +-- +2.14.1 + + diff --git a/ovsdb-server-Don-t-drop-all-connections-on-read-writ.patch b/ovsdb-server-Don-t-drop-all-connections-on-read-writ.patch new file mode 100644 index 0000000..372e81a --- /dev/null +++ b/ovsdb-server-Don-t-drop-all-connections-on-read-writ.patch @@ -0,0 +1,92 @@ +From 8190df660ca6e8f58a579323bd5503c9357c9f21 Mon Sep 17 00:00:00 2001 +From: Numan Siddique +Date: Mon, 14 Oct 2019 20:50:02 +0530 +Subject: ovsdb-server: Don't drop all connections on read/write status change. + +The commit [1] force drops all connections when the db read/write status changes. +Prior to the commit [1], when there was read/write status change, the existing +jsonrpc sessions with 'db_change_aware' set to true, were not updated with the +changed 'read_only' value. If the db status was changed to 'standby', the existing +clients could still write to the db. + +In the case of pacemaker OVN HA, OVN OCF script 'start' action starts the +ovsdb-servers in read-only state and later, it sets to read-write in the +'promote' action. We have observed that if some ovn-controllers connect to +the SB ovsdb-server (in read-only state) just before the 'promote' action, +the connection is not reset all the times and these ovn-controllers remain connected +to the SB ovsdb-server in read-only state all the time. Even though +the commit [1] calls 'ovsdb_jsonrpc_server_reconnect()' with 'forced' flag +set to true when the db read/write status changes, somehow the FSM misses resetting +the connections of these ovn-controllers. + +I think this needs to be addressed in the FSM. This patch doesn't address +this FSM issue. Instead it changes the behavior of 'ovsdb_jsonrpc_server_set_read_only()' +by setting the 'read_only' flag of all the jsonrpc sessions instead of forcefully +resetting the connection. + +I think there is no need to reset the connection. In large scale production +deployements with OVN, this results in unnecessary waste of CPU cycles as ovn-controllers +will have to connect twice - once during 'start' action and again during 'promote'. + +[1] - 2a9679e3b2c6("ovsdb-server: drop all connections on read/write status change") + +Acked-by: Dumitru Ceara +Signed-off-by: Numan Siddique +Signed-off-by: Ben Pfaff +--- + ovsdb/jsonrpc-server.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c +index ddbbc2e94..4e2dfc3d7 100644 +--- a/ovsdb/jsonrpc-server.c ++++ b/ovsdb/jsonrpc-server.c +@@ -80,6 +80,8 @@ static void ovsdb_jsonrpc_session_unlock_all(struct ovsdb_jsonrpc_session *); + static void ovsdb_jsonrpc_session_unlock__(struct ovsdb_lock_waiter *); + static void ovsdb_jsonrpc_session_send(struct ovsdb_jsonrpc_session *, + struct jsonrpc_msg *); ++static void ovsdb_jsonrpc_session_set_readonly_all( ++ struct ovsdb_jsonrpc_remote *remote, bool read_only); + + /* Triggers. */ + static void ovsdb_jsonrpc_trigger_create(struct ovsdb_jsonrpc_session *, +@@ -365,10 +367,13 @@ ovsdb_jsonrpc_server_set_read_only(struct ovsdb_jsonrpc_server *svr, + { + if (svr->read_only != read_only) { + svr->read_only = read_only; +- ovsdb_jsonrpc_server_reconnect(svr, true, +- xstrdup(read_only +- ? "making server read-only" +- : "making server read/write")); ++ ++ struct shash_node *node; ++ SHASH_FOR_EACH (node, &svr->remotes) { ++ struct ovsdb_jsonrpc_remote *remote = node->data; ++ ++ ovsdb_jsonrpc_session_set_readonly_all(remote, read_only); ++ } + } + } + +@@ -670,6 +675,17 @@ ovsdb_jsonrpc_session_reconnect_all(struct ovsdb_jsonrpc_remote *remote, + } + } + ++static void ++ovsdb_jsonrpc_session_set_readonly_all(struct ovsdb_jsonrpc_remote *remote, ++ bool read_only) ++{ ++ struct ovsdb_jsonrpc_session *s; ++ ++ LIST_FOR_EACH (s, node, &remote->sessions) { ++ s->read_only = read_only; ++ } ++} ++ + /* Sets the options for all of the JSON-RPC sessions managed by 'remote' to + * 'options'. + * +-- +2.14.1 + + diff --git a/ovsdb-server-fix-memory-leak-while-converting-databa.patch b/ovsdb-server-fix-memory-leak-while-converting-databa.patch new file mode 100644 index 0000000..18a4802 --- /dev/null +++ b/ovsdb-server-fix-memory-leak-while-converting-databa.patch @@ -0,0 +1,61 @@ +From c70272a165b018ac6808fe27bba0b461ed2894b5 Mon Sep 17 00:00:00 2001 +From: Damijan Skvarc +Date: Fri, 25 Oct 2019 14:22:58 +0200 +Subject: ovsdb-server: fix memory leak while converting database + +Memory leak happens while converting existing database into new +database according to the specified schema (ovsdb-client convert +new-schema). Memory leak was detected by valgrind while executing +functional test "schema conversion online - clustered" + +==16202== 96 bytes in 6 blocks are definitely lost in loss record 326 of 399 +==16202== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==16202== by 0x44A5D4: xmalloc (util.c:138) +==16202== by 0x4377A6: alloc_default_atoms (ovsdb-data.c:315) +==16202== by 0x437F18: ovsdb_datum_init_default (ovsdb-data.c:918) +==16202== by 0x413D82: ovsdb_row_create (row.c:59) +==16202== by 0x40AA53: ovsdb_convert_table (file.c:220) +==16202== by 0x40AA53: ovsdb_convert (file.c:275) +==16202== by 0x416BE1: ovsdb_trigger_try (trigger.c:255) +==16202== by 0x40D29E: ovsdb_jsonrpc_trigger_create (jsonrpc-server.c:1119) +==16202== by 0x40D29E: ovsdb_jsonrpc_session_got_request (jsonrpc-server.c:986) +==16202== by 0x40D29E: ovsdb_jsonrpc_session_run (jsonrpc-server.c:556) +==16202== by 0x40D29E: ovsdb_jsonrpc_session_run_all (jsonrpc-server.c:586) +==16202== by 0x40D29E: ovsdb_jsonrpc_server_run (jsonrpc-server.c:401) +==16202== by 0x40682E: main_loop (ovsdb-server.c:209) +==16202== by 0x40682E: main (ovsdb-server.c:460) + +The problem was in ovsdb_datum_convert() function, which overrides +pointers to datum memory allocated in ovsdb_row_create() function. +Fix was done by freeing this memory before ovsdb_datum_convert() +is called. + +Signed-off-by: Damijan Skvarc +Signed-off-by: Ben Pfaff +--- + ovsdb/file.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/ovsdb/file.c b/ovsdb/file.c +index 8d16b097b..0af077fce 100644 +--- a/ovsdb/file.c ++++ b/ovsdb/file.c +@@ -235,10 +235,14 @@ ovsdb_convert_table(struct ovsdb_txn *txn, + continue; + } + ++ ovsdb_datum_destroy(&dst_row->fields[dst_column->index], ++ &dst_column->type); ++ + struct ovsdb_error *error = ovsdb_datum_convert( + &dst_row->fields[dst_column->index], &dst_column->type, + &src_row->fields[src_column->index], &src_column->type); + if (error) { ++ ovsdb_datum_init_empty(&dst_row->fields[dst_column->index]); + ovsdb_row_destroy(dst_row); + return error; + } +-- +2.14.1 + + diff --git a/ovsdb-server-fix-memory-leak-while-deleting-zone.patch b/ovsdb-server-fix-memory-leak-while-deleting-zone.patch new file mode 100644 index 0000000..dc3c231 --- /dev/null +++ b/ovsdb-server-fix-memory-leak-while-deleting-zone.patch @@ -0,0 +1,63 @@ +From 28eb1e4336bb916437d57000c874a4f55ec229d9 Mon Sep 17 00:00:00 2001 +From: Damijan Skvarc +Date: Tue, 12 Nov 2019 12:32:35 +0100 +Subject: ovsdb-server: fix memory leak while deleting zone + +memory leak was detected by valgrind during execution +of "database commands -- positive checks" test. + +leaked memory was allocated in ovsdb_execute_mutate() function +while parsing mutations from the apparent json entity: + +==19563== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==19563== by 0x4652D0: xmalloc (util.c:138) +==19563== by 0x46539E: xmemdup0 (util.c:168) +==19563== by 0x4653F7: xstrdup (util.c:177) +==19563== by 0x450379: ovsdb_base_type_clone (ovsdb-types.c:208) +==19563== by 0x450F8D: ovsdb_type_clone (ovsdb-types.c:550) +==19563== by 0x428C3F: ovsdb_mutation_from_json (mutation.c:108) +==19563== by 0x428F6B: ovsdb_mutation_set_from_json (mutation.c:187) +==19563== by 0x42578D: ovsdb_execute_mutate (execution.c:573) +==19563== by 0x4246B0: ovsdb_execute_compose (execution.c:171) +==19563== by 0x41CDE5: ovsdb_trigger_try (trigger.c:204) +==19563== by 0x41C8DF: ovsdb_trigger_init (trigger.c:61) +==19563== by 0x40E93C: ovsdb_jsonrpc_trigger_create (jsonrpc-server.c:1135) +==19563== by 0x40E20C: ovsdb_jsonrpc_session_got_request (jsonrpc-server.c:1002) +==19563== by 0x40D1C2: ovsdb_jsonrpc_session_run (jsonrpc-server.c:561) +==19563== by 0x40D31E: ovsdb_jsonrpc_session_run_all (jsonrpc-server.c:591) +==19563== by 0x40CD6E: ovsdb_jsonrpc_server_run (jsonrpc-server.c:406) +==19563== by 0x40627E: main_loop (ovsdb-server.c:209) +==19563== by 0x406E66: main (ovsdb-server.c:460) + +This memory is usually freed at the end of ovsdb_execute_mutate() +however in the aforementioned test case this does not happen. Namely +in case of delete mutator and in case of error while calling ovsdb_datum_from_json() +apparent mutation was marked as invalid, what prevents freeing problematic memory. + +Memory leak can be reproduced quickly with the following command sequence: +ovs-vsctl --no-wait -vreconnect:emer add-zone-tp netdev zone=1 icmp_first=1 icmp_reply=2 +ovs-vsctl --no-wait -vreconnect:emer del-zone-tp netdev zone=1 + +Signed-off-by: Damijan Skvarc +Signed-off-by: Ben Pfaff +--- + ovsdb/mutation.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ovsdb/mutation.c b/ovsdb/mutation.c +index cd20bdb7c..56edc5f00 100644 +--- a/ovsdb/mutation.c ++++ b/ovsdb/mutation.c +@@ -147,6 +147,8 @@ ovsdb_mutation_from_json(const struct ovsdb_table_schema *ts, + if (error && ovsdb_type_is_map(&m->type) + && m->mutator == OVSDB_M_DELETE) { + ovsdb_error_destroy(error); ++ ovsdb_base_type_destroy(&m->type.value); ++ m->type.value.enum_ = NULL; + m->type.value.type = OVSDB_TYPE_VOID; + error = ovsdb_datum_from_json(&m->arg, &m->type, array->elems[2], + symtab); +-- +2.14.1 + + diff --git a/raft-Free-leaked-json-data.patch b/raft-Free-leaked-json-data.patch new file mode 100644 index 0000000..4b00040 --- /dev/null +++ b/raft-Free-leaked-json-data.patch @@ -0,0 +1,51 @@ +From 71d0bf666b826da8441c3f1bd3f49ff1917423b3 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:27 -0700 +Subject: raft: Free leaked json data + +Valgrind reported: + +1924: compacting online - cluster + +==29312== 2,886 (240 direct, 2,646 indirect) bytes in 6 blocks are definitely lost in loss record 406 of 413 +==29312== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==29312== by 0x44A5F4: xmalloc (util.c:138) +==29312== by 0x4308EA: json_create (json.c:1451) +==29312== by 0x4308EA: json_object_create (json.c:254) +==29312== by 0x430ED0: json_parser_push_object (json.c:1273) +==29312== by 0x430ED0: json_parser_input (json.c:1371) +==29312== by 0x431CF1: json_lex_input (json.c:991) +==29312== by 0x43233B: json_parser_feed (json.c:1149) +==29312== by 0x41D87F: parse_body.isra.0 (log.c:411) +==29312== by 0x41E141: ovsdb_log_read (log.c:476) +==29312== by 0x42646D: raft_read_log (raft.c:866) +==29312== by 0x42646D: raft_open (raft.c:951) +==29312== by 0x4151AF: ovsdb_storage_open__ (storage.c:81) +==29312== by 0x408FFC: open_db (ovsdb-server.c:642) +==29312== by 0x40657F: main (ovsdb-server.c:358) + +This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + ovsdb/raft.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ovsdb/raft.c b/ovsdb/raft.c +index 9eabe2cfe..a45c7f8ba 100644 +--- a/ovsdb/raft.c ++++ b/ovsdb/raft.c +@@ -883,6 +883,7 @@ raft_read_log(struct raft *raft) + error = raft_apply_record(raft, i, &r); + raft_record_uninit(&r); + } ++ json_destroy(json); + if (error) { + return ovsdb_wrap_error(error, "error reading record %llu from " + "%s log", i, raft->name); +-- +2.14.1 + + diff --git a/rhel-Fix-ovs-kmod-manage.sh-that-may-create-invalid-.patch b/rhel-Fix-ovs-kmod-manage.sh-that-may-create-invalid-.patch new file mode 100644 index 0000000..06992fa --- /dev/null +++ b/rhel-Fix-ovs-kmod-manage.sh-that-may-create-invalid-.patch @@ -0,0 +1,55 @@ +From 7fbfaf9c5ca7a722bf1887afa6f2a7a45af61b7c Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Mon, 18 Nov 2019 12:06:26 -0800 +Subject:rhel: Fix ovs-kmod-manage.sh that may create invalid soft links + +Current code iterates every kernel under '/lib/modules' for a matched +version. As a result, this script may create invalid soft links if the +matched kernel doesn't have openvswitch-kmod RPM installed. + +This patch fixes it. + +VMWare-BZ: #2257534 + +Fixes: c3570519 ("rhel: add 4.4 kernel in kmod build with mulitple versions, fedora") +Signed-off-by: Yifeng Sun +Acked-by: Yi-Hung Wei +Signed-off-by: William Tu +--- + rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh b/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh +index 693fb0b74..8464a6fbc 100644 +--- a/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh ++++ b/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh +@@ -151,7 +151,7 @@ fi + #$kmod_high_ver" + + found_match=false +-for kname in `ls -d /lib/modules/*` ++for kname in $kversion; + do + IFS='.\|-' read -r -a pkg_ver_nums <<<"${kname}" + pkg_ver=${pkg_ver_nums[$ver_offset]} +@@ -178,14 +178,14 @@ if [ "$found_match" = "false" ]; then + exit 1 + fi + +-if [ "$requested_kernel" != "/lib/modules/$current_kernel" ]; then ++if [ "$requested_kernel" != "$current_kernel" ]; then + if [ ! -d /lib/modules/$current_kernel/weak-updates/openvswitch ]; then + mkdir -p /lib/modules/$current_kernel/weak-updates + mkdir -p /lib/modules/$current_kernel/weak-updates/openvswitch + fi + for m in openvswitch vport-gre vport-stt vport-geneve \ + vport-lisp vport-vxlan; do +- ln -f -s $requested_kernel/extra/openvswitch/$m.ko \ ++ ln -f -s /lib/modules/$requested_kernel/extra/openvswitch/$m.ko \ + /lib/modules/$current_kernel/weak-updates/openvswitch/$m.ko + done + else +-- +2.14.1 + + diff --git a/rhel-Support-RHEL-7.8-kernel-module-rpm-build.patch b/rhel-Support-RHEL-7.8-kernel-module-rpm-build.patch new file mode 100644 index 0000000..bbd99ca --- /dev/null +++ b/rhel-Support-RHEL-7.8-kernel-module-rpm-build.patch @@ -0,0 +1,78 @@ +From b1cbbabb7154478ea938494cfe811586c54df70e Mon Sep 17 00:00:00 2001 +From: Yi-Hung Wei +Date: Wed, 4 Dec 2019 17:10:27 -0800 +Subject: rhel: Support RHEL 7.8 kernel module rpm build + +This patch supports RHEL 7.8 kernel module rpm package building. + +$ make rpm-fedora-kmod \ +RPMBUILD_OPT='-D "kversion 3.10.0-1101.el7.x86_64"' + +Signed-off-by: Yi-Hung Wei +Reviewed-by: Yifeng Sun +Signed-off-by: William Tu +--- + rhel/openvswitch-kmod-fedora.spec.in | 14 +++++++++----- + rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh | 6 ++++++ + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/rhel/openvswitch-kmod-fedora.spec.in b/rhel/openvswitch-kmod-fedora.spec.in +index fbb836699..c94f2f535 100644 +--- a/rhel/openvswitch-kmod-fedora.spec.in ++++ b/rhel/openvswitch-kmod-fedora.spec.in +@@ -12,9 +12,12 @@ + # Use the kversion macro such as + # RPMBUILD_OPT='-D "kversion 3.10.0-693.1.1.el7.x86_64 3.10.0-693.17.1.el7.x86_64"' + # to build package for mulitple kernel versions in the same package +-# This only works for kernel 3.10.0 major revision 1062 (RHEL 7.7), +-# major revision 957 (RHEL 7.6), major revision 693 (RHEL 7.4) and +-# major revision 327 (RHEL 7.2). ++# This only works for the following kernels. ++# - 3.10.0 major revision 327 (RHEL 7.2) ++# - 3.10.0 major revision 693 (RHEL 7.4) ++# - 3.10.0 major revision 957 (RHEL 7.6) ++# - 3.10.0 major revision 1062 (RHEL 7.7) ++# - 3.10.0 major revision 1101 (RHEL 7.8) + # By default, build against the current running kernel version + #%define kernel 3.1.5-1.fc16.x86_64 + #define kernel %{kernel_source} +@@ -93,8 +96,9 @@ if grep -qs "suse" /etc/os-release; then + fi + elif [ "$mainline_major" = "3" ] && [ "$mainline_minor" = "10" ] && + { [ "$major_rev" = "327" ] || [ "$major_rev" = "693" ] || \ +- [ "$major_rev" = "957" ] || [ "$major_rev" == "1062" ]; }; then +- # For RHEL 7.2, 7.4, 7.6 and 7.7 ++ [ "$major_rev" = "957" ] || [ "$major_rev" == "1062" ] || \ ++ [ "$major_rev" = "1101" ]; }; then ++ # 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 + fi +diff --git a/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh b/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh +index a252b391e..a9b5cdd81 100644 +--- a/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh ++++ b/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh +@@ -19,6 +19,7 @@ + # - 3.10.0 major revision 693 (RHEL 7.4) + # - 3.10.0 major revision 957 (RHEL 7.6) + # - 3.10.0 major revision 1062 (RHEL 7.7) ++# - 3.10.0 major revision 1101 (RHEL 7.8) + # - 4.4.x, x >= 73 (SLES 12 SP3) + # - 4.12.x, x >= 14 (SLES 12 SP4). + # It is packaged in the openvswitch kmod RPM and run in the post-install +@@ -106,6 +107,11 @@ if [ "$mainline_major" = "3" ] && [ "$mainline_minor" = "10" ]; then + comp_ver=10 + ver_offset=4 + installed_ver="$minor_rev" ++ elif [ "$major_rev" = "1101" ]; then ++# echo "rhel78" ++ comp_ver=10 ++ ver_offset=4 ++ installed_ver="$minor_rev" + fi + elif [ "$mainline_major" = "4" ] && [ "$mainline_minor" = "4" ]; then + if [ "$mainline_patch" -ge "73" ]; then +-- +2.14.1 + + diff --git a/rhel-Support-RHEL7.7-build-and-packaging.patch b/rhel-Support-RHEL7.7-build-and-packaging.patch new file mode 100644 index 0000000..6b7af9c --- /dev/null +++ b/rhel-Support-RHEL7.7-build-and-packaging.patch @@ -0,0 +1,90 @@ +From 817fae6b5482911db7610ab7cd5fbd5ad4d6ad36 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Fri, 11 Oct 2019 14:49:14 -0700 +Subject: rhel: Support RHEL7.7 build and packaging + +This patch provides essential fixes for OVS to support +RHEL7.7's new kernel. + +make rpm-fedora-kmod \ +RPMBUILD_OPT='-D "kversion 3.10.0-1062.1.2.el7.x86_64"' + +Tested-by: Greg Rose +Reviewed-by: Greg Rose +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + rhel/openvswitch-kmod-fedora.spec.in | 9 +++++---- + rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh | 14 ++++++++++---- + 2 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/rhel/openvswitch-kmod-fedora.spec.in b/rhel/openvswitch-kmod-fedora.spec.in +index b3588982e..fbb836699 100644 +--- a/rhel/openvswitch-kmod-fedora.spec.in ++++ b/rhel/openvswitch-kmod-fedora.spec.in +@@ -12,8 +12,9 @@ + # Use the kversion macro such as + # RPMBUILD_OPT='-D "kversion 3.10.0-693.1.1.el7.x86_64 3.10.0-693.17.1.el7.x86_64"' + # to build package for mulitple kernel versions in the same package +-# This only works for kernel 3.10.0 major revision 957 (RHEL 7.6), +-# major revision 693 (RHEL 7.4) and major revision 327 (RHEL 7.2). ++# This only works for kernel 3.10.0 major revision 1062 (RHEL 7.7), ++# major revision 957 (RHEL 7.6), major revision 693 (RHEL 7.4) and ++# major revision 327 (RHEL 7.2). + # By default, build against the current running kernel version + #%define kernel 3.1.5-1.fc16.x86_64 + #define kernel %{kernel_source} +@@ -92,8 +93,8 @@ if grep -qs "suse" /etc/os-release; then + fi + elif [ "$mainline_major" = "3" ] && [ "$mainline_minor" = "10" ] && + { [ "$major_rev" = "327" ] || [ "$major_rev" = "693" ] || \ +- [ "$major_rev" = "957" ]; }; then +- # For RHEL 7.2, 7.4 and 7.6 ++ [ "$major_rev" = "957" ] || [ "$major_rev" == "1062" ]; }; then ++ # For RHEL 7.2, 7.4, 7.6 and 7.7 + if [ -x "%{_datadir}/openvswitch/scripts/ovs-kmod-manage.sh" ]; then + %{_datadir}/openvswitch/scripts/ovs-kmod-manage.sh + fi +diff --git a/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh b/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh +index 8464a6fbc..a252b391e 100644 +--- a/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh ++++ b/rhel/usr_share_openvswitch_scripts_ovs-kmod-manage.sh +@@ -15,9 +15,10 @@ + # limitations under the License. + + # This script is intended to be used on the following kernels. +-# - 3.10.0 major revision 327 (RHEL 7.2) +-# - 3.10.0 major revision 693 (RHEL 7.4) +-# - 3.10.0 major revision 957 (RHEL 7.6) ++# - 3.10.0 major revision 327 (RHEL 7.2) ++# - 3.10.0 major revision 693 (RHEL 7.4) ++# - 3.10.0 major revision 957 (RHEL 7.6) ++# - 3.10.0 major revision 1062 (RHEL 7.7) + # - 4.4.x, x >= 73 (SLES 12 SP3) + # - 4.12.x, x >= 14 (SLES 12 SP4). + # It is packaged in the openvswitch kmod RPM and run in the post-install +@@ -100,6 +101,11 @@ if [ "$mainline_major" = "3" ] && [ "$mainline_minor" = "10" ]; then + comp_ver=10 + ver_offset=4 + installed_ver="$minor_rev" ++ elif [ "$major_rev" = "1062" ]; then ++# echo "rhel77" ++ comp_ver=10 ++ ver_offset=4 ++ installed_ver="$minor_rev" + fi + elif [ "$mainline_major" = "4" ] && [ "$mainline_minor" = "4" ]; then + if [ "$mainline_patch" -ge "73" ]; then +@@ -111,7 +117,7 @@ elif [ "$mainline_major" = "4" ] && [ "$mainline_minor" = "4" ]; then + elif [ "$mainline_major" = "4" ] && [ "$mainline_minor" = "12" ]; then + if [ "$mainline_patch" -ge "14" ]; then + # echo "sles12sp4" +- comp_ver=14 ++ comp_ver=1 + ver_offset=2 + installed_ver="$mainline_patch" + fi +-- +2.14.1 + + diff --git a/rhel-openvswitch-fedora.spec.in-Fix-output-redirect-.patch b/rhel-openvswitch-fedora.spec.in-Fix-output-redirect-.patch new file mode 100644 index 0000000..94a175f --- /dev/null +++ b/rhel-openvswitch-fedora.spec.in-Fix-output-redirect-.patch @@ -0,0 +1,31 @@ +From 479770e869295df0912da541062064b49a838ab1 Mon Sep 17 00:00:00 2001 +From: Roi Dayan +Date: Mon, 28 Oct 2019 10:37:44 +0200 +Subject: rhel: openvswitch-fedora.spec.in: Fix output redirect to null device + +Add missing slash. + +Fixes: 0447019df7c6 ("fedora-spec: added systemd post/postun/pre/preun sections") +Signed-off-by: Roi Dayan +Signed-off-by: Simon Horman +--- + rhel/openvswitch-fedora.spec.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in +index 9c752ff4e..aff357263 100644 +--- a/rhel/openvswitch-fedora.spec.in ++++ b/rhel/openvswitch-fedora.spec.in +@@ -396,7 +396,7 @@ fi + %else + # Package install, not upgrade + if [ $1 -eq 1 ]; then +- /bin/systemctl daemon-reload >dev/null || : ++ /bin/systemctl daemon-reload >/dev/null || : + fi + %endif + +-- +2.14.1 + + diff --git a/sparse-Get-rid-of-obsolete-rte_flow-header.patch b/sparse-Get-rid-of-obsolete-rte_flow-header.patch new file mode 100644 index 0000000..58f6d90 --- /dev/null +++ b/sparse-Get-rid-of-obsolete-rte_flow-header.patch @@ -0,0 +1,1559 @@ +From be6d19b2f162df5341f144cd0970b6cea150b36a Mon Sep 17 00:00:00 2001 +From: David Marchand +Date: Thu, 3 Oct 2019 20:11:24 +0200 +Subject: sparse: Get rid of obsolete rte_flow header. + +This header had been copied to cope with issues on the dpdk side. +Now that the problems have been fixed [1], let's drop this file as it is +now out of sync with dpdk. + +1: https://git.dpdk.org/dpdk/commit/?id=fbb25a3878cc + +Signed-off-by: David Marchand +Signed-off-by: Ian Stokes +--- + include/sparse/automake.mk | 1 - + include/sparse/rte_flow.h | 1518 -------------------------------------------- + 2 files changed, 1519 deletions(-) + delete mode 100644 include/sparse/rte_flow.h + +diff --git a/include/sparse/automake.mk b/include/sparse/automake.mk +index f65c27255..8f3e12dce 100644 +--- a/include/sparse/automake.mk ++++ b/include/sparse/automake.mk +@@ -1,7 +1,6 @@ + noinst_HEADERS += \ + include/sparse/rte_byteorder.h \ + include/sparse/rte_esp.h \ +- include/sparse/rte_flow.h \ + include/sparse/rte_icmp.h \ + include/sparse/rte_ip.h \ + include/sparse/rte_sctp.h \ +diff --git a/include/sparse/rte_flow.h b/include/sparse/rte_flow.h +deleted file mode 100644 +index 02fa523b4..000000000 +--- a/include/sparse/rte_flow.h ++++ /dev/null +@@ -1,1518 +0,0 @@ +-/*- +- * BSD LICENSE +- * +- * Copyright 2016 6WIND S.A. +- * Copyright 2016 Mellanox. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in +- * the documentation and/or other materials provided with the +- * distribution. +- * * Neither the name of 6WIND S.A. nor the names of its +- * contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +- +-#ifndef __CHECKER__ +-#error "Use this header only with sparse. It is not a correct implementation." +-#endif +- +-#ifndef RTE_FLOW_H_ +-#define RTE_FLOW_H_ +- +-/** +- * @file +- * RTE generic flow API +- * +- * This interface provides the ability to program packet matching and +- * associated actions in hardware through flow rules. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +-/** +- * Flow rule attributes. +- * +- * Priorities are set on two levels: per group and per rule within groups. +- * +- * Lower values denote higher priority, the highest priority for both levels +- * is 0, so that a rule with priority 0 in group 8 is always matched after a +- * rule with priority 8 in group 0. +- * +- * Although optional, applications are encouraged to group similar rules as +- * much as possible to fully take advantage of hardware capabilities +- * (e.g. optimized matching) and work around limitations (e.g. a single +- * pattern type possibly allowed in a given group). +- * +- * Group and priority levels are arbitrary and up to the application, they +- * do not need to be contiguous nor start from 0, however the maximum number +- * varies between devices and may be affected by existing flow rules. +- * +- * If a packet is matched by several rules of a given group for a given +- * priority level, the outcome is undefined. It can take any path, may be +- * duplicated or even cause unrecoverable errors. +- * +- * Note that support for more than a single group and priority level is not +- * guaranteed. +- * +- * Flow rules can apply to inbound and/or outbound traffic (ingress/egress). +- * +- * Several pattern items and actions are valid and can be used in both +- * directions. Those valid for only one direction are described as such. +- * +- * At least one direction must be specified. +- * +- * Specifying both directions at once for a given rule is not recommended +- * but may be valid in a few cases (e.g. shared counter). +- */ +-struct rte_flow_attr { +- uint32_t group; /**< Priority group. */ +- uint32_t priority; /**< Priority level within group. */ +- uint32_t ingress:1; /**< Rule applies to ingress traffic. */ +- uint32_t egress:1; /**< Rule applies to egress traffic. */ +- uint32_t reserved:30; /**< Reserved, must be zero. */ +-}; +- +-/** +- * Matching pattern item types. +- * +- * Pattern items fall in two categories: +- * +- * - Matching protocol headers and packet data (ANY, RAW, ETH, VLAN, IPV4, +- * IPV6, ICMP, UDP, TCP, SCTP, VXLAN and so on), usually associated with a +- * specification structure. These must be stacked in the same order as the +- * protocol layers to match, starting from the lowest. +- * +- * - Matching meta-data or affecting pattern processing (END, VOID, INVERT, +- * PF, VF, PORT and so on), often without a specification structure. Since +- * they do not match packet contents, these can be specified anywhere +- * within item lists without affecting others. +- * +- * See the description of individual types for more information. Those +- * marked with [META] fall into the second category. +- */ +-enum rte_flow_item_type { +- /** +- * [META] +- * +- * End marker for item lists. Prevents further processing of items, +- * thereby ending the pattern. +- * +- * No associated specification structure. +- */ +- RTE_FLOW_ITEM_TYPE_END, +- +- /** +- * [META] +- * +- * Used as a placeholder for convenience. It is ignored and simply +- * discarded by PMDs. +- * +- * No associated specification structure. +- */ +- RTE_FLOW_ITEM_TYPE_VOID, +- +- /** +- * [META] +- * +- * Inverted matching, i.e. process packets that do not match the +- * pattern. +- * +- * No associated specification structure. +- */ +- RTE_FLOW_ITEM_TYPE_INVERT, +- +- /** +- * Matches any protocol in place of the current layer, a single ANY +- * may also stand for several protocol layers. +- * +- * See struct rte_flow_item_any. +- */ +- RTE_FLOW_ITEM_TYPE_ANY, +- +- /** +- * [META] +- * +- * Matches packets addressed to the physical function of the device. +- * +- * If the underlying device function differs from the one that would +- * normally receive the matched traffic, specifying this item +- * prevents it from reaching that device unless the flow rule +- * contains a PF action. Packets are not duplicated between device +- * instances by default. +- * +- * No associated specification structure. +- */ +- RTE_FLOW_ITEM_TYPE_PF, +- +- /** +- * [META] +- * +- * Matches packets addressed to a virtual function ID of the device. +- * +- * If the underlying device function differs from the one that would +- * normally receive the matched traffic, specifying this item +- * prevents it from reaching that device unless the flow rule +- * contains a VF action. Packets are not duplicated between device +- * instances by default. +- * +- * See struct rte_flow_item_vf. +- */ +- RTE_FLOW_ITEM_TYPE_VF, +- +- /** +- * [META] +- * +- * Matches packets coming from the specified physical port of the +- * underlying device. +- * +- * The first PORT item overrides the physical port normally +- * associated with the specified DPDK input port (port_id). This +- * item can be provided several times to match additional physical +- * ports. +- * +- * See struct rte_flow_item_port. +- */ +- RTE_FLOW_ITEM_TYPE_PORT, +- +- /** +- * Matches a byte string of a given length at a given offset. +- * +- * See struct rte_flow_item_raw. +- */ +- RTE_FLOW_ITEM_TYPE_RAW, +- +- /** +- * Matches an Ethernet header. +- * +- * See struct rte_flow_item_eth. +- */ +- RTE_FLOW_ITEM_TYPE_ETH, +- +- /** +- * Matches an 802.1Q/ad VLAN tag. +- * +- * See struct rte_flow_item_vlan. +- */ +- RTE_FLOW_ITEM_TYPE_VLAN, +- +- /** +- * Matches an IPv4 header. +- * +- * See struct rte_flow_item_ipv4. +- */ +- RTE_FLOW_ITEM_TYPE_IPV4, +- +- /** +- * Matches an IPv6 header. +- * +- * See struct rte_flow_item_ipv6. +- */ +- RTE_FLOW_ITEM_TYPE_IPV6, +- +- /** +- * Matches an ICMP header. +- * +- * See struct rte_flow_item_icmp. +- */ +- RTE_FLOW_ITEM_TYPE_ICMP, +- +- /** +- * Matches a UDP header. +- * +- * See struct rte_flow_item_udp. +- */ +- RTE_FLOW_ITEM_TYPE_UDP, +- +- /** +- * Matches a TCP header. +- * +- * See struct rte_flow_item_tcp. +- */ +- RTE_FLOW_ITEM_TYPE_TCP, +- +- /** +- * Matches a SCTP header. +- * +- * See struct rte_flow_item_sctp. +- */ +- RTE_FLOW_ITEM_TYPE_SCTP, +- +- /** +- * Matches a VXLAN header. +- * +- * See struct rte_flow_item_vxlan. +- */ +- RTE_FLOW_ITEM_TYPE_VXLAN, +- +- /** +- * Matches a E_TAG header. +- * +- * See struct rte_flow_item_e_tag. +- */ +- RTE_FLOW_ITEM_TYPE_E_TAG, +- +- /** +- * Matches a NVGRE header. +- * +- * See struct rte_flow_item_nvgre. +- */ +- RTE_FLOW_ITEM_TYPE_NVGRE, +- +- /** +- * Matches a MPLS header. +- * +- * See struct rte_flow_item_mpls. +- */ +- RTE_FLOW_ITEM_TYPE_MPLS, +- +- /** +- * Matches a GRE header. +- * +- * See struct rte_flow_item_gre. +- */ +- RTE_FLOW_ITEM_TYPE_GRE, +- +- /** +- * [META] +- * +- * Fuzzy pattern match, expect faster than default. +- * +- * This is for device that support fuzzy matching option. +- * Usually a fuzzy matching is fast but the cost is accuracy. +- * +- * See struct rte_flow_item_fuzzy. +- */ +- RTE_FLOW_ITEM_TYPE_FUZZY, +- +- /** +- * Matches a GTP header. +- * +- * Configure flow for GTP packets. +- * +- * See struct rte_flow_item_gtp. +- */ +- RTE_FLOW_ITEM_TYPE_GTP, +- +- /** +- * Matches a GTP header. +- * +- * Configure flow for GTP-C packets. +- * +- * See struct rte_flow_item_gtp. +- */ +- RTE_FLOW_ITEM_TYPE_GTPC, +- +- /** +- * Matches a GTP header. +- * +- * Configure flow for GTP-U packets. +- * +- * See struct rte_flow_item_gtp. +- */ +- RTE_FLOW_ITEM_TYPE_GTPU, +- +- /** +- * Matches a ESP header. +- * +- * See struct rte_flow_item_esp. +- */ +- RTE_FLOW_ITEM_TYPE_ESP, +-}; +- +-/** +- * RTE_FLOW_ITEM_TYPE_ANY +- * +- * Matches any protocol in place of the current layer, a single ANY may also +- * stand for several protocol layers. +- * +- * This is usually specified as the first pattern item when looking for a +- * protocol anywhere in a packet. +- * +- * A zeroed mask stands for any number of layers. +- */ +-struct rte_flow_item_any { +- uint32_t num; /**< Number of layers covered. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_ANY. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_any rte_flow_item_any_mask = { +- .num = 0x00000000, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_VF +- * +- * Matches packets addressed to a virtual function ID of the device. +- * +- * If the underlying device function differs from the one that would +- * normally receive the matched traffic, specifying this item prevents it +- * from reaching that device unless the flow rule contains a VF +- * action. Packets are not duplicated between device instances by default. +- * +- * - Likely to return an error or never match any traffic if this causes a +- * VF device to match traffic addressed to a different VF. +- * - Can be specified multiple times to match traffic addressed to several +- * VF IDs. +- * - Can be combined with a PF item to match both PF and VF traffic. +- * +- * A zeroed mask can be used to match any VF ID. +- */ +-struct rte_flow_item_vf { +- uint32_t id; /**< Destination VF ID. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_VF. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_vf rte_flow_item_vf_mask = { +- .id = 0x00000000, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_PORT +- * +- * Matches packets coming from the specified physical port of the underlying +- * device. +- * +- * The first PORT item overrides the physical port normally associated with +- * the specified DPDK input port (port_id). This item can be provided +- * several times to match additional physical ports. +- * +- * Note that physical ports are not necessarily tied to DPDK input ports +- * (port_id) when those are not under DPDK control. Possible values are +- * specific to each device, they are not necessarily indexed from zero and +- * may not be contiguous. +- * +- * As a device property, the list of allowed values as well as the value +- * associated with a port_id should be retrieved by other means. +- * +- * A zeroed mask can be used to match any port index. +- */ +-struct rte_flow_item_port { +- uint32_t index; /**< Physical port index. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_PORT. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_port rte_flow_item_port_mask = { +- .index = 0x00000000, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_RAW +- * +- * Matches a byte string of a given length at a given offset. +- * +- * Offset is either absolute (using the start of the packet) or relative to +- * the end of the previous matched item in the stack, in which case negative +- * values are allowed. +- * +- * If search is enabled, offset is used as the starting point. The search +- * area can be delimited by setting limit to a nonzero value, which is the +- * maximum number of bytes after offset where the pattern may start. +- * +- * Matching a zero-length pattern is allowed, doing so resets the relative +- * offset for subsequent items. +- * +- * This type does not support ranges (struct rte_flow_item.last). +- */ +-struct rte_flow_item_raw { +- uint32_t relative:1; /**< Look for pattern after the previous item. */ +- uint32_t search:1; /**< Search pattern from offset (see also limit). */ +- uint32_t reserved:30; /**< Reserved, must be set to zero. */ +- int32_t offset; /**< Absolute or relative offset for pattern. */ +- uint16_t limit; /**< Search area limit for start of pattern. */ +- uint16_t length; /**< Pattern length. */ +- uint8_t pattern[]; /**< Byte string to look for. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_RAW. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_raw rte_flow_item_raw_mask = { +- .relative = 1, +- .search = 1, +- .reserved = 0x3fffffff, +- .offset = 0xffffffff, +- .limit = 0xffff, +- .length = 0xffff, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_ETH +- * +- * Matches an Ethernet header. +- */ +-struct rte_flow_item_eth { +- struct ether_addr dst; /**< Destination MAC. */ +- struct ether_addr src; /**< Source MAC. */ +- rte_be16_t type; /**< EtherType. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_ETH. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_eth rte_flow_item_eth_mask = { +- .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", +- .src.addr_bytes = "\xff\xff\xff\xff\xff\xff", +- .type = RTE_BE16(0x0000), +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_VLAN +- * +- * Matches an 802.1Q/ad VLAN tag. +- * +- * The corresponding standard outer EtherType (TPID) values are +- * ETHER_TYPE_VLAN or ETHER_TYPE_QINQ. It can be overridden by the preceding +- * pattern item. +- */ +-struct rte_flow_item_vlan { +- rte_be16_t tci; /**< Tag control information. */ +- rte_be16_t inner_type; /**< Inner EtherType or TPID. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_VLAN. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_vlan rte_flow_item_vlan_mask = { +- .tci = RTE_BE16(0x0fff), +- .inner_type = RTE_BE16(0x0000), +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_IPV4 +- * +- * Matches an IPv4 header. +- * +- * Note: IPv4 options are handled by dedicated pattern items. +- */ +-struct rte_flow_item_ipv4 { +- struct ipv4_hdr hdr; /**< IPv4 header definition. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_IPV4. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_ipv4 rte_flow_item_ipv4_mask = { +- .hdr = { +- .src_addr = RTE_BE32(0xffffffff), +- .dst_addr = RTE_BE32(0xffffffff), +- }, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_IPV6. +- * +- * Matches an IPv6 header. +- * +- * Note: IPv6 options are handled by dedicated pattern items. +- */ +-struct rte_flow_item_ipv6 { +- struct ipv6_hdr hdr; /**< IPv6 header definition. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = { +- .hdr = { +- .src_addr = +- "\xff\xff\xff\xff\xff\xff\xff\xff" +- "\xff\xff\xff\xff\xff\xff\xff\xff", +- .dst_addr = +- "\xff\xff\xff\xff\xff\xff\xff\xff" +- "\xff\xff\xff\xff\xff\xff\xff\xff", +- }, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_ICMP. +- * +- * Matches an ICMP header. +- */ +-struct rte_flow_item_icmp { +- struct icmp_hdr hdr; /**< ICMP header definition. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_icmp rte_flow_item_icmp_mask = { +- .hdr = { +- .icmp_type = 0xff, +- .icmp_code = 0xff, +- }, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_UDP. +- * +- * Matches a UDP header. +- */ +-struct rte_flow_item_udp { +- struct udp_hdr hdr; /**< UDP header definition. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_UDP. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_udp rte_flow_item_udp_mask = { +- .hdr = { +- .src_port = RTE_BE16(0xffff), +- .dst_port = RTE_BE16(0xffff), +- }, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_TCP. +- * +- * Matches a TCP header. +- */ +-struct rte_flow_item_tcp { +- struct tcp_hdr hdr; /**< TCP header definition. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_TCP. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_tcp rte_flow_item_tcp_mask = { +- .hdr = { +- .src_port = RTE_BE16(0xffff), +- .dst_port = RTE_BE16(0xffff), +- }, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_SCTP. +- * +- * Matches a SCTP header. +- */ +-struct rte_flow_item_sctp { +- struct sctp_hdr hdr; /**< SCTP header definition. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_SCTP. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_sctp rte_flow_item_sctp_mask = { +- .hdr = { +- .src_port = RTE_BE16(0xffff), +- .dst_port = RTE_BE16(0xffff), +- }, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_VXLAN. +- * +- * Matches a VXLAN header (RFC 7348). +- */ +-struct rte_flow_item_vxlan { +- uint8_t flags; /**< Normally 0x08 (I flag). */ +- uint8_t rsvd0[3]; /**< Reserved, normally 0x000000. */ +- uint8_t vni[3]; /**< VXLAN identifier. */ +- uint8_t rsvd1; /**< Reserved, normally 0x00. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_VXLAN. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_vxlan rte_flow_item_vxlan_mask = { +- .vni = "\xff\xff\xff", +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_E_TAG. +- * +- * Matches a E-tag header. +- */ +-struct rte_flow_item_e_tag { +- rte_be16_t tpid; /**< Tag protocol identifier (0x893F). */ +- /** +- * E-Tag control information (E-TCI). +- * E-PCP (3b), E-DEI (1b), ingress E-CID base (12b). +- */ +- rte_be16_t epcp_edei_in_ecid_b; +- /** Reserved (2b), GRP (2b), E-CID base (12b). */ +- rte_be16_t rsvd_grp_ecid_b; +- uint8_t in_ecid_e; /**< Ingress E-CID ext. */ +- uint8_t ecid_e; /**< E-CID ext. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_E_TAG. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_e_tag rte_flow_item_e_tag_mask = { +- .rsvd_grp_ecid_b = RTE_BE16(0x3fff), +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_NVGRE. +- * +- * Matches a NVGRE header. +- */ +-struct rte_flow_item_nvgre { +- /** +- * Checksum (1b), undefined (1b), key bit (1b), sequence number (1b), +- * reserved 0 (9b), version (3b). +- * +- * c_k_s_rsvd0_ver must have value 0x2000 according to RFC 7637. +- */ +- rte_be16_t c_k_s_rsvd0_ver; +- rte_be16_t protocol; /**< Protocol type (0x6558). */ +- uint8_t tni[3]; /**< Virtual subnet ID. */ +- uint8_t flow_id; /**< Flow ID. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_NVGRE. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_nvgre rte_flow_item_nvgre_mask = { +- .tni = "\xff\xff\xff", +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_MPLS. +- * +- * Matches a MPLS header. +- */ +-struct rte_flow_item_mpls { +- /** +- * Label (20b), TC (3b), Bottom of Stack (1b). +- */ +- uint8_t label_tc_s[3]; +- uint8_t ttl; /** Time-to-Live. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_MPLS. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_mpls rte_flow_item_mpls_mask = { +- .label_tc_s = "\xff\xff\xf0", +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_GRE. +- * +- * Matches a GRE header. +- */ +-struct rte_flow_item_gre { +- /** +- * Checksum (1b), reserved 0 (12b), version (3b). +- * Refer to RFC 2784. +- */ +- rte_be16_t c_rsvd0_ver; +- rte_be16_t protocol; /**< Protocol type. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_GRE. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_gre rte_flow_item_gre_mask = { +- .protocol = RTE_BE16(0xffff), +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_FUZZY +- * +- * Fuzzy pattern match, expect faster than default. +- * +- * This is for device that support fuzzy match option. +- * Usually a fuzzy match is fast but the cost is accuracy. +- * i.e. Signature Match only match pattern's hash value, but it is +- * possible two different patterns have the same hash value. +- * +- * Matching accuracy level can be configure by threshold. +- * Driver can divide the range of threshold and map to different +- * accuracy levels that device support. +- * +- * Threshold 0 means perfect match (no fuzziness), while threshold +- * 0xffffffff means fuzziest match. +- */ +-struct rte_flow_item_fuzzy { +- uint32_t thresh; /**< Accuracy threshold. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_FUZZY. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_fuzzy rte_flow_item_fuzzy_mask = { +- .thresh = 0xffffffff, +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_GTP. +- * +- * Matches a GTPv1 header. +- */ +-struct rte_flow_item_gtp { +- /** +- * Version (3b), protocol type (1b), reserved (1b), +- * Extension header flag (1b), +- * Sequence number flag (1b), +- * N-PDU number flag (1b). +- */ +- uint8_t v_pt_rsv_flags; +- uint8_t msg_type; /**< Message type. */ +- rte_be16_t msg_len; /**< Message length. */ +- rte_be32_t teid; /**< Tunnel endpoint identifier. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_GTP. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_gtp rte_flow_item_gtp_mask = { +- .teid = RTE_BE32(0xffffffff), +-}; +-#endif +- +-/** +- * RTE_FLOW_ITEM_TYPE_ESP +- * +- * Matches an ESP header. +- */ +-struct rte_flow_item_esp { +- struct esp_hdr hdr; /**< ESP header definition. */ +-}; +- +-/** Default mask for RTE_FLOW_ITEM_TYPE_ESP. */ +-#ifndef __cplusplus +-static const struct rte_flow_item_esp rte_flow_item_esp_mask = { +- .hdr = { +- .spi = OVS_BE32_MAX, +- }, +-}; +-#endif +- +-/** +- * Matching pattern item definition. +- * +- * A pattern is formed by stacking items starting from the lowest protocol +- * layer to match. This stacking restriction does not apply to meta items +- * which can be placed anywhere in the stack without affecting the meaning +- * of the resulting pattern. +- * +- * Patterns are terminated by END items. +- * +- * The spec field should be a valid pointer to a structure of the related +- * item type. It may remain unspecified (NULL) in many cases to request +- * broad (nonspecific) matching. In such cases, last and mask must also be +- * set to NULL. +- * +- * Optionally, last can point to a structure of the same type to define an +- * inclusive range. This is mostly supported by integer and address fields, +- * may cause errors otherwise. Fields that do not support ranges must be set +- * to 0 or to the same value as the corresponding fields in spec. +- * +- * Only the fields defined to nonzero values in the default masks (see +- * rte_flow_item_{name}_mask constants) are considered relevant by +- * default. This can be overridden by providing a mask structure of the +- * same type with applicable bits set to one. It can also be used to +- * partially filter out specific fields (e.g. as an alternate mean to match +- * ranges of IP addresses). +- * +- * Mask is a simple bit-mask applied before interpreting the contents of +- * spec and last, which may yield unexpected results if not used +- * carefully. For example, if for an IPv4 address field, spec provides +- * 10.1.2.3, last provides 10.3.4.5 and mask provides 255.255.0.0, the +- * effective range becomes 10.1.0.0 to 10.3.255.255. +- */ +-struct rte_flow_item { +- enum rte_flow_item_type type; /**< Item type. */ +- const void *spec; /**< Pointer to item specification structure. */ +- const void *last; /**< Defines an inclusive range (spec to last). */ +- const void *mask; /**< Bit-mask applied to spec and last. */ +-}; +- +-/** +- * Action types. +- * +- * Each possible action is represented by a type. Some have associated +- * configuration structures. Several actions combined in a list can be +- * affected to a flow rule. That list is not ordered. +- * +- * They fall in three categories: +- * +- * - Terminating actions (such as QUEUE, DROP, RSS, PF, VF) that prevent +- * processing matched packets by subsequent flow rules, unless overridden +- * with PASSTHRU. +- * +- * - Non terminating actions (PASSTHRU, DUP) that leave matched packets up +- * for additional processing by subsequent flow rules. +- * +- * - Other non terminating meta actions that do not affect the fate of +- * packets (END, VOID, MARK, FLAG, COUNT). +- * +- * When several actions are combined in a flow rule, they should all have +- * different types (e.g. dropping a packet twice is not possible). +- * +- * Only the last action of a given type is taken into account. PMDs still +- * perform error checking on the entire list. +- * +- * Note that PASSTHRU is the only action able to override a terminating +- * rule. +- */ +-enum rte_flow_action_type { +- /** +- * [META] +- * +- * End marker for action lists. Prevents further processing of +- * actions, thereby ending the list. +- * +- * No associated configuration structure. +- */ +- RTE_FLOW_ACTION_TYPE_END, +- +- /** +- * [META] +- * +- * Used as a placeholder for convenience. It is ignored and simply +- * discarded by PMDs. +- * +- * No associated configuration structure. +- */ +- RTE_FLOW_ACTION_TYPE_VOID, +- +- /** +- * Leaves packets up for additional processing by subsequent flow +- * rules. This is the default when a rule does not contain a +- * terminating action, but can be specified to force a rule to +- * become non-terminating. +- * +- * No associated configuration structure. +- */ +- RTE_FLOW_ACTION_TYPE_PASSTHRU, +- +- /** +- * [META] +- * +- * Attaches an integer value to packets and sets PKT_RX_FDIR and +- * PKT_RX_FDIR_ID mbuf flags. +- * +- * See struct rte_flow_action_mark. +- */ +- RTE_FLOW_ACTION_TYPE_MARK, +- +- /** +- * [META] +- * +- * Flags packets. Similar to MARK without a specific value; only +- * sets the PKT_RX_FDIR mbuf flag. +- * +- * No associated configuration structure. +- */ +- RTE_FLOW_ACTION_TYPE_FLAG, +- +- /** +- * Assigns packets to a given queue index. +- * +- * See struct rte_flow_action_queue. +- */ +- RTE_FLOW_ACTION_TYPE_QUEUE, +- +- /** +- * Drops packets. +- * +- * PASSTHRU overrides this action if both are specified. +- * +- * No associated configuration structure. +- */ +- RTE_FLOW_ACTION_TYPE_DROP, +- +- /** +- * [META] +- * +- * Enables counters for this rule. +- * +- * These counters can be retrieved and reset through rte_flow_query(), +- * see struct rte_flow_query_count. +- * +- * No associated configuration structure. +- */ +- RTE_FLOW_ACTION_TYPE_COUNT, +- +- /** +- * Duplicates packets to a given queue index. +- * +- * This is normally combined with QUEUE, however when used alone, it +- * is actually similar to QUEUE + PASSTHRU. +- * +- * See struct rte_flow_action_dup. +- */ +- RTE_FLOW_ACTION_TYPE_DUP, +- +- /** +- * Similar to QUEUE, except RSS is additionally performed on packets +- * to spread them among several queues according to the provided +- * parameters. +- * +- * See struct rte_flow_action_rss. +- */ +- RTE_FLOW_ACTION_TYPE_RSS, +- +- /** +- * Redirects packets to the physical function (PF) of the current +- * device. +- * +- * No associated configuration structure. +- */ +- RTE_FLOW_ACTION_TYPE_PF, +- +- /** +- * Redirects packets to the virtual function (VF) of the current +- * device with the specified ID. +- * +- * See struct rte_flow_action_vf. +- */ +- RTE_FLOW_ACTION_TYPE_VF, +- +- /** +- * Traffic metering and policing (MTR). +- * +- * See struct rte_flow_action_meter. +- * See file rte_mtr.h for MTR object configuration. +- */ +- RTE_FLOW_ACTION_TYPE_METER, +- +- /** +- * Redirects packets to security engine of current device for security +- * processing as specified by security session. +- * +- * See struct rte_flow_action_security. +- */ +- RTE_FLOW_ACTION_TYPE_SECURITY +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_MARK +- * +- * Attaches an integer value to packets and sets PKT_RX_FDIR and +- * PKT_RX_FDIR_ID mbuf flags. +- * +- * This value is arbitrary and application-defined. Maximum allowed value +- * depends on the underlying implementation. It is returned in the +- * hash.fdir.hi mbuf field. +- */ +-struct rte_flow_action_mark { +- uint32_t id; /**< Integer value to return with packets. */ +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_QUEUE +- * +- * Assign packets to a given queue index. +- * +- * Terminating by default. +- */ +-struct rte_flow_action_queue { +- uint16_t index; /**< Queue index to use. */ +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_COUNT (query) +- * +- * Query structure to retrieve and reset flow rule counters. +- */ +-struct rte_flow_query_count { +- uint32_t reset:1; /**< Reset counters after query [in]. */ +- uint32_t hits_set:1; /**< hits field is set [out]. */ +- uint32_t bytes_set:1; /**< bytes field is set [out]. */ +- uint32_t reserved:29; /**< Reserved, must be zero [in, out]. */ +- uint64_t hits; /**< Number of hits for this rule [out]. */ +- uint64_t bytes; /**< Number of bytes through this rule [out]. */ +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_DUP +- * +- * Duplicates packets to a given queue index. +- * +- * This is normally combined with QUEUE, however when used alone, it is +- * actually similar to QUEUE + PASSTHRU. +- * +- * Non-terminating by default. +- */ +-struct rte_flow_action_dup { +- uint16_t index; /**< Queue index to duplicate packets to. */ +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_RSS +- * +- * Similar to QUEUE, except RSS is additionally performed on packets to +- * spread them among several queues according to the provided parameters. +- * +- * Unlike global RSS settings used by other DPDK APIs, unsetting the +- * @p types field does not disable RSS in a flow rule. Doing so instead +- * requests safe unspecified "best-effort" settings from the underlying PMD, +- * which depending on the flow rule, may result in anything ranging from +- * empty (single queue) to all-inclusive RSS. +- * +- * Note: RSS hash result is stored in the hash.rss mbuf field which overlaps +- * hash.fdir.lo. Since the MARK action sets the hash.fdir.hi field only, +- * both can be requested simultaneously. +- */ +-struct rte_flow_action_rss { +- enum rte_eth_hash_function func; /**< RSS hash function to apply. */ +- /** +- * Packet encapsulation level RSS hash @p types apply to. +- * +- * - @p 0 requests the default behavior. Depending on the packet +- * type, it can mean outermost, innermost, anything in between or +- * even no RSS. +- * +- * It basically stands for the innermost encapsulation level RSS +- * can be performed on according to PMD and device capabilities. +- * +- * - @p 1 requests RSS to be performed on the outermost packet +- * encapsulation level. +- * +- * - @p 2 and subsequent values request RSS to be performed on the +- * specified inner packet encapsulation level, from outermost to +- * innermost (lower to higher values). +- * +- * Values other than @p 0 are not necessarily supported. +- * +- * Requesting a specific RSS level on unrecognized traffic results +- * in undefined behavior. For predictable results, it is recommended +- * to make the flow rule pattern match packet headers up to the +- * requested encapsulation level so that only matching traffic goes +- * through. +- */ +- uint32_t level; +- uint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */ +- uint32_t key_len; /**< Hash key length in bytes. */ +- uint32_t queue_num; /**< Number of entries in @p queue. */ +- const uint8_t *key; /**< Hash key. */ +- const uint16_t *queue; /**< Queue indices to use. */ +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_VF +- * +- * Redirects packets to a virtual function (VF) of the current device. +- * +- * Packets matched by a VF pattern item can be redirected to their original +- * VF ID instead of the specified one. This parameter may not be available +- * and is not guaranteed to work properly if the VF part is matched by a +- * prior flow rule or if packets are not addressed to a VF in the first +- * place. +- * +- * Terminating by default. +- */ +-struct rte_flow_action_vf { +- uint32_t original:1; /**< Use original VF ID if possible. */ +- uint32_t reserved:31; /**< Reserved, must be zero. */ +- uint32_t id; /**< VF ID to redirect packets to. */ +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_METER +- * +- * Traffic metering and policing (MTR). +- * +- * Packets matched by items of this type can be either dropped or passed to the +- * next item with their color set by the MTR object. +- * +- * Non-terminating by default. +- */ +-struct rte_flow_action_meter { +- uint32_t mtr_id; /**< MTR object ID created with rte_mtr_create(). */ +-}; +- +-/** +- * RTE_FLOW_ACTION_TYPE_SECURITY +- * +- * Perform the security action on flows matched by the pattern items +- * according to the configuration of the security session. +- * +- * This action modifies the payload of matched flows. For INLINE_CRYPTO, the +- * security protocol headers and IV are fully provided by the application as +- * specified in the flow pattern. The payload of matching packets is +- * encrypted on egress, and decrypted and authenticated on ingress. +- * For INLINE_PROTOCOL, the security protocol is fully offloaded to HW, +- * providing full encapsulation and decapsulation of packets in security +- * protocols. The flow pattern specifies both the outer security header fields +- * and the inner packet fields. The security session specified in the action +- * must match the pattern parameters. +- * +- * The security session specified in the action must be created on the same +- * port as the flow action that is being specified. +- * +- * The ingress/egress flow attribute should match that specified in the +- * security session if the security session supports the definition of the +- * direction. +- * +- * Multiple flows can be configured to use the same security session. +- * +- * Non-terminating by default. +- */ +-struct rte_flow_action_security { +- void *security_session; /**< Pointer to security session structure. */ +-}; +- +-/** +- * Definition of a single action. +- * +- * A list of actions is terminated by a END action. +- * +- * For simple actions without a configuration structure, conf remains NULL. +- */ +-struct rte_flow_action { +- enum rte_flow_action_type type; /**< Action type. */ +- const void *conf; /**< Pointer to action configuration structure. */ +-}; +- +-/** +- * Opaque type returned after successfully creating a flow. +- * +- * This handle can be used to manage and query the related flow (e.g. to +- * destroy it or retrieve counters). +- */ +-struct rte_flow; +- +-/** +- * Verbose error types. +- * +- * Most of them provide the type of the object referenced by struct +- * rte_flow_error.cause. +- */ +-enum rte_flow_error_type { +- RTE_FLOW_ERROR_TYPE_NONE, /**< No error. */ +- RTE_FLOW_ERROR_TYPE_UNSPECIFIED, /**< Cause unspecified. */ +- RTE_FLOW_ERROR_TYPE_HANDLE, /**< Flow rule (handle). */ +- RTE_FLOW_ERROR_TYPE_ATTR_GROUP, /**< Group field. */ +- RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, /**< Priority field. */ +- RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, /**< Ingress field. */ +- RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, /**< Egress field. */ +- RTE_FLOW_ERROR_TYPE_ATTR, /**< Attributes structure. */ +- RTE_FLOW_ERROR_TYPE_ITEM_NUM, /**< Pattern length. */ +- RTE_FLOW_ERROR_TYPE_ITEM, /**< Specific pattern item. */ +- RTE_FLOW_ERROR_TYPE_ACTION_NUM, /**< Number of actions. */ +- RTE_FLOW_ERROR_TYPE_ACTION, /**< Specific action. */ +-}; +- +-/** +- * Verbose error structure definition. +- * +- * This object is normally allocated by applications and set by PMDs, the +- * message points to a constant string which does not need to be freed by +- * the application, however its pointer can be considered valid only as long +- * as its associated DPDK port remains configured. Closing the underlying +- * device or unloading the PMD invalidates it. +- * +- * Both cause and message may be NULL regardless of the error type. +- */ +-struct rte_flow_error { +- enum rte_flow_error_type type; /**< Cause field and error types. */ +- const void *cause; /**< Object responsible for the error. */ +- const char *message; /**< Human-readable error message. */ +-}; +- +-/** +- * Check whether a flow rule can be created on a given port. +- * +- * The flow rule is validated for correctness and whether it could be accepted +- * by the device given sufficient resources. The rule is checked against the +- * current device mode and queue configuration. The flow rule may also +- * optionally be validated against existing flow rules and device resources. +- * This function has no effect on the target device. +- * +- * The returned value is guaranteed to remain valid only as long as no +- * successful calls to rte_flow_create() or rte_flow_destroy() are made in +- * the meantime and no device parameter affecting flow rules in any way are +- * modified, due to possible collisions or resource limitations (although in +- * such cases EINVAL should not be returned). +- * +- * @param port_id +- * Port identifier of Ethernet device. +- * @param[in] attr +- * Flow rule attributes. +- * @param[in] pattern +- * Pattern specification (list terminated by the END pattern item). +- * @param[in] actions +- * Associated actions (list terminated by the END action). +- * @param[out] error +- * Perform verbose error reporting if not NULL. PMDs initialize this +- * structure in case of error only. +- * +- * @return +- * 0 if flow rule is valid and can be created. A negative errno value +- * otherwise (rte_errno is also set), the following errors are defined: +- * +- * -ENOSYS: underlying device does not support this functionality. +- * +- * -EINVAL: unknown or invalid rule specification. +- * +- * -ENOTSUP: valid but unsupported rule specification (e.g. partial +- * bit-masks are unsupported). +- * +- * -EEXIST: collision with an existing rule. Only returned if device +- * supports flow rule collision checking and there was a flow rule +- * collision. Not receiving this return code is no guarantee that creating +- * the rule will not fail due to a collision. +- * +- * -ENOMEM: not enough memory to execute the function, or if the device +- * supports resource validation, resource limitation on the device. +- * +- * -EBUSY: action cannot be performed due to busy device resources, may +- * succeed if the affected queues or even the entire port are in a stopped +- * state (see rte_eth_dev_rx_queue_stop() and rte_eth_dev_stop()). +- */ +-int +-rte_flow_validate(uint16_t port_id, +- const struct rte_flow_attr *attr, +- const struct rte_flow_item pattern[], +- const struct rte_flow_action actions[], +- struct rte_flow_error *error); +- +-/** +- * Create a flow rule on a given port. +- * +- * @param port_id +- * Port identifier of Ethernet device. +- * @param[in] attr +- * Flow rule attributes. +- * @param[in] pattern +- * Pattern specification (list terminated by the END pattern item). +- * @param[in] actions +- * Associated actions (list terminated by the END action). +- * @param[out] error +- * Perform verbose error reporting if not NULL. PMDs initialize this +- * structure in case of error only. +- * +- * @return +- * A valid handle in case of success, NULL otherwise and rte_errno is set +- * to the positive version of one of the error codes defined for +- * rte_flow_validate(). +- */ +-struct rte_flow * +-rte_flow_create(uint16_t port_id, +- const struct rte_flow_attr *attr, +- const struct rte_flow_item pattern[], +- const struct rte_flow_action actions[], +- struct rte_flow_error *error); +- +-/** +- * Destroy a flow rule on a given port. +- * +- * Failure to destroy a flow rule handle may occur when other flow rules +- * depend on it, and destroying it would result in an inconsistent state. +- * +- * This function is only guaranteed to succeed if handles are destroyed in +- * reverse order of their creation. +- * +- * @param port_id +- * Port identifier of Ethernet device. +- * @param flow +- * Flow rule handle to destroy. +- * @param[out] error +- * Perform verbose error reporting if not NULL. PMDs initialize this +- * structure in case of error only. +- * +- * @return +- * 0 on success, a negative errno value otherwise and rte_errno is set. +- */ +-int +-rte_flow_destroy(uint16_t port_id, +- struct rte_flow *flow, +- struct rte_flow_error *error); +- +-/** +- * Destroy all flow rules associated with a port. +- * +- * In the unlikely event of failure, handles are still considered destroyed +- * and no longer valid but the port must be assumed to be in an inconsistent +- * state. +- * +- * @param port_id +- * Port identifier of Ethernet device. +- * @param[out] error +- * Perform verbose error reporting if not NULL. PMDs initialize this +- * structure in case of error only. +- * +- * @return +- * 0 on success, a negative errno value otherwise and rte_errno is set. +- */ +-int +-rte_flow_flush(uint16_t port_id, +- struct rte_flow_error *error); +- +-/** +- * Query an existing flow rule. +- * +- * This function allows retrieving flow-specific data such as counters. +- * Data is gathered by special actions which must be present in the flow +- * rule definition. +- * +- * \see RTE_FLOW_ACTION_TYPE_COUNT +- * +- * @param port_id +- * Port identifier of Ethernet device. +- * @param flow +- * Flow rule handle to query. +- * @param action +- * Action type to query. +- * @param[in, out] data +- * Pointer to storage for the associated query data type. +- * @param[out] error +- * Perform verbose error reporting if not NULL. PMDs initialize this +- * structure in case of error only. +- * +- * @return +- * 0 on success, a negative errno value otherwise and rte_errno is set. +- */ +-int +-rte_flow_query(uint16_t port_id, +- struct rte_flow *flow, +- enum rte_flow_action_type action, +- void *data, +- struct rte_flow_error *error); +- +-/** +- * Restrict ingress traffic to the defined flow rules. +- * +- * Isolated mode guarantees that all ingress traffic comes from defined flow +- * rules only (current and future). +- * +- * Besides making ingress more deterministic, it allows PMDs to safely reuse +- * resources otherwise assigned to handle the remaining traffic, such as +- * global RSS configuration settings, VLAN filters, MAC address entries, +- * legacy filter API rules and so on in order to expand the set of possible +- * flow rule types. +- * +- * Calling this function as soon as possible after device initialization, +- * ideally before the first call to rte_eth_dev_configure(), is recommended +- * to avoid possible failures due to conflicting settings. +- * +- * Once effective, leaving isolated mode may not be possible depending on +- * PMD implementation. +- * +- * Additionally, the following functionality has no effect on the underlying +- * port and may return errors such as ENOTSUP ("not supported"): +- * +- * - Toggling promiscuous mode. +- * - Toggling allmulticast mode. +- * - Configuring MAC addresses. +- * - Configuring multicast addresses. +- * - Configuring VLAN filters. +- * - Configuring Rx filters through the legacy API (e.g. FDIR). +- * - Configuring global RSS settings. +- * +- * @param port_id +- * Port identifier of Ethernet device. +- * @param set +- * Nonzero to enter isolated mode, attempt to leave it otherwise. +- * @param[out] error +- * Perform verbose error reporting if not NULL. PMDs initialize this +- * structure in case of error only. +- * +- * @return +- * 0 on success, a negative errno value otherwise and rte_errno is set. +- */ +-int +-rte_flow_isolate(uint16_t port_id, int set, struct rte_flow_error *error); +- +-/** +- * Initialize flow error structure. +- * +- * @param[out] error +- * Pointer to flow error structure (may be NULL). +- * @param code +- * Related error code (rte_errno). +- * @param type +- * Cause field and error types. +- * @param cause +- * Object responsible for the error. +- * @param message +- * Human-readable error message. +- * +- * @return +- * Negative error code (errno value) and rte_errno is set. +- */ +-int +-rte_flow_error_set(struct rte_flow_error *error, +- int code, +- enum rte_flow_error_type type, +- const void *cause, +- const char *message); +- +-/** +- * Generic flow representation. +- * +- * This form is sufficient to describe an rte_flow independently from any +- * PMD implementation and allows for replayability and identification. +- */ +-struct rte_flow_desc { +- size_t size; /**< Allocated space including data[]. */ +- struct rte_flow_attr attr; /**< Attributes. */ +- struct rte_flow_item *items; /**< Items. */ +- struct rte_flow_action *actions; /**< Actions. */ +- uint8_t data[]; /**< Storage for items/actions. */ +-}; +- +-/** +- * Copy an rte_flow rule description. +- * +- * @param[in] fd +- * Flow rule description. +- * @param[in] len +- * Total size of allocated data for the flow description. +- * @param[in] attr +- * Flow rule attributes. +- * @param[in] items +- * Pattern specification (list terminated by the END pattern item). +- * @param[in] actions +- * Associated actions (list terminated by the END action). +- * +- * @return +- * If len is greater or equal to the size of the flow, the total size of the +- * flow description and its data. +- * If len is lower than the size of the flow, the number of bytes that would +- * have been written to desc had it been sufficient. Nothing is written. +- */ +-size_t +-rte_flow_copy(struct rte_flow_desc *fd, size_t len, +- const struct rte_flow_attr *attr, +- const struct rte_flow_item *items, +- const struct rte_flow_action *actions); +- +-#ifdef __cplusplus +-} +-#endif +- +-#endif /* RTE_FLOW_H_ */ +-- +2.14.1 + + diff --git a/stream_ssl-fix-important-memory-leak-in-ssl_connect-.patch b/stream_ssl-fix-important-memory-leak-in-ssl_connect-.patch new file mode 100644 index 0000000..c0c3d97 --- /dev/null +++ b/stream_ssl-fix-important-memory-leak-in-ssl_connect-.patch @@ -0,0 +1,249 @@ +From 1a860302fd8f547396320669fd896b3aab0c6583 Mon Sep 17 00:00:00 2001 +From: Damijan Skvarc +Date: Fri, 20 Sep 2019 09:51:54 -0700 +Subject: stream_ssl: fix important memory leak in ssl_connect() function + +While checking valgrind reports after running "make check-valgrind" I have noticed +reports for several tests similar to the following: + +.... +==5345== Memcheck, a memory error detector +==5345== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. +==5345== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info +==5345== Command: ovsdb-client --private-key=/home/damijan.skvarc/doma/ovs/tests/testpki-privkey.pem --certificate=/home/damijan.skvarc/doma/ovs/tests/testpki-cert.pem --ca-cert=/home/damijan.skvarc/doma/ovs/tests/testpki-cacert.pem transact ssl:127.0.0.1:40111 \ \ \ ["ordinals", +==5345== \ \ \ \ \ \ {"op":\ "update", +==5345== \ \ \ \ \ \ \ "table":\ "ordinals", +==5345== \ \ \ \ \ \ \ "where":\ [["number",\ "==",\ 1]], +==5345== \ \ \ \ \ \ \ "row":\ {"number":\ 2,\ "name":\ "old\ two"}}, +==5345== \ \ \ \ \ \ {"op":\ "update", +==5345== \ \ \ \ \ \ \ "table":\ "ordinals", +==5345== \ \ \ \ \ \ \ "where":\ [["name",\ "==",\ "two"]], +==5345== \ \ \ \ \ \ \ "row":\ {"number":\ 1,\ "name":\ "old\ one"}}] +==5345== Parent PID: 5344 +==5345== +==5345== +==5345== HEAP SUMMARY: +==5345== in use at exit: 116,551 bytes in 3,341 blocks +==5345== total heap usage: 5,134 allocs, 1,793 frees, 412,290 bytes allocated +==5345== +==5345== 6,221 (184 direct, 6,037 indirect) bytes in 1 blocks are definitely lost in loss record 498 of 500 +==5345== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==5345== by 0x5105E77: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5345== by 0x51E1D23: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5345== by 0x51E4861: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5345== by 0x51E5414: ASN1_item_ex_d2i (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5345== by 0x51E546A: ASN1_item_d2i (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5345== by 0x4E56B27: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) +==5345== by 0x4E5BA11: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) +==5345== by 0x4E65145: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) +==5345== by 0x4522DF: ssl_connect (stream-ssl.c:530) +==5345== by 0x443D38: scs_connecting (stream.c:315) +==5345== by 0x443D38: stream_connect (stream.c:338) +==5345== by 0x443FA1: stream_open_block (stream.c:266) +==5345== by 0x40AB79: open_jsonrpc (ovsdb-client.c:507) +==5345== by 0x40AB79: open_rpc (ovsdb-client.c:143) +==5345== by 0x40B06B: do_transact__ (ovsdb-client.c:871) +==5345== by 0x40B245: do_transact (ovsdb-client.c:893) +==5345== by 0x405F76: main (ovsdb-client.c:282) +==5345== +==5345== LEAK SUMMARY: +==5345== definitely lost: 184 bytes in 1 blocks +==5345== indirectly lost: 6,037 bytes in 117 blocks +==5345== possibly lost: 0 bytes in 0 blocks +==5345== still reachable: 110,330 bytes in 3,223 blocks +==5345== suppressed: 0 bytes in 0 blocks +==5345== Reachable blocks (those to which a pointer was found) are not shown. +==5345== To see them, rerun with: --leak-check=full --show-leak-kinds=all +==5345== +==5345== For counts of detected and suppressed errors, rerun with: -v +==5345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) +.... + +This report was extracted from "index uniqueness checking" test and complains about +leaking memory in ovsdb-client application. The problem is not huge, since ovsdb-client +is CLI tool which is constantly reinvoked/restarted, thus leaked memory is not accumulated. + +More problematic issue is that for the same test valgrind reports the similar problem also for +ovsdb-server: + +.... +==5290== Memcheck, a memory error detector +==5290== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. +==5290== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info +==5290== Command: ovsdb-server --log-file --detach --no-chdir --pidfile --private-key=/home/damijan.skvarc/doma/ovs/tests/testpki-privkey2.pem --certificate=/home/damijan.skvarc/doma/ovs/tests/testpki-cert2.pem --ca-cert=/home/damijan.skvarc/doma/ovs/tests/testpki-cacert.pem --remote=pssl:0:127.0.0.1 db +==5290== Parent PID: 5289 +==5290== +==5292== Warning: noted but unhandled ioctl 0x2403 with no size/direction hints. +==5292== This could cause spurious value errors to appear. +==5292== See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper. +==5292== Warning: noted but unhandled ioctl 0x2400 with no size/direction hints. +==5292== This could cause spurious value errors to appear. +==5292== See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper. +==5290== +==5290== HEAP SUMMARY: +==5290== in use at exit: 2,066 bytes in 48 blocks +==5290== total heap usage: 87 allocs, 39 frees, 14,152 bytes allocated +==5290== +==5290== LEAK SUMMARY: +==5290== definitely lost: 0 bytes in 0 blocks +==5290== indirectly lost: 0 bytes in 0 blocks +==5290== possibly lost: 0 bytes in 0 blocks +==5290== still reachable: 2,066 bytes in 48 blocks +==5290== suppressed: 0 bytes in 0 blocks +==5290== Reachable blocks (those to which a pointer was found) are not shown. +==5290== To see them, rerun with: --leak-check=full --show-leak-kinds=all +==5290== +==5290== For counts of detected and suppressed errors, rerun with: -v +==5290== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1) +==5292== Warning: noted but unhandled ioctl 0x2401 with no size/direction hints. +==5292== This could cause spurious value errors to appear. +==5292== See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper. +==5292== +==5292== HEAP SUMMARY: +==5292== in use at exit: 164,018 bytes in 4,252 blocks +==5292== total heap usage: 17,910 allocs, 13,658 frees, 1,907,468 bytes allocated +==5292== +==5292== 49,720 (1,472 direct, 48,248 indirect) bytes in 8 blocks are definitely lost in loss record 580 of 580 +==5292== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==5292== by 0x5105E77: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5292== by 0x51E1D23: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5292== by 0x51E4861: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5292== by 0x51E5414: ASN1_item_ex_d2i (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5292== by 0x51E546A: ASN1_item_d2i (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) +==5292== by 0x4E53E00: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) +==5292== by 0x4E55727: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) +==5292== by 0x452C4B: ssl_connect (stream-ssl.c:530) +==5292== by 0x445B18: scs_connecting (stream.c:315) +==5292== by 0x445B18: stream_connect (stream.c:338) +==5292== by 0x445B91: stream_recv (stream.c:369) +==5292== by 0x432A9C: jsonrpc_recv.part.7 (jsonrpc.c:310) +==5292== by 0x433977: jsonrpc_recv (jsonrpc.c:1139) +==5292== by 0x433977: jsonrpc_session_recv (jsonrpc.c:1112) +==5292== by 0x40CCE3: ovsdb_jsonrpc_session_run (jsonrpc-server.c:553) +==5292== by 0x40CCE3: ovsdb_jsonrpc_session_run_all (jsonrpc-server.c:586) +==5292== by 0x40CCE3: ovsdb_jsonrpc_server_run (jsonrpc-server.c:401) +==5292== by 0x40682E: main_loop (ovsdb-server.c:209) +==5292== by 0x40682E: main (ovsdb-server.c:460) +==5292== +==5292== LEAK SUMMARY: +==5292== definitely lost: 1,472 bytes in 8 blocks +==5292== indirectly lost: 48,248 bytes in 936 blocks +==5292== possibly lost: 0 bytes in 0 blocks +==5292== still reachable: 114,298 bytes in 3,308 blocks +==5292== suppressed: 0 bytes in 0 blocks +==5292== Reachable blocks (those to which a pointer was found) are not shown. +==5292== To see them, rerun with: --leak-check=full --show-leak-kinds=all +==5292== +==5292== For counts of detected and suppressed errors, rerun with: -v +==5292== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1) +.... + +In this case ovsdb-server is running as daemon process (--detach option) and leaking memory is +accumulated whenever ovsdb-client is reconnected. Within observed test ovsdb-client CLI tool +connects 8 times to ovsdb-server. Leaked memory in ovsdb-client (for each invocation) is approx. +6K bytes, while leaked memory in ovsdb-server is aprox. 48Kbytes what is actually 8*6K. Thus per +each connection both ovsdb-client and ovsdb-server leak approx. 6K bytes. + +I have done a small manual test to check if ovsdb-server is indeed accumulating leaked memory +by dumping ovsdb-server in a loop: + +console1: +ovsdb-server \ +--log-file \ +--detach --no-chdir --pidfile \ +--private-key=testpki-privkey2.pem \ +--certificate=testpki-cert2.pem \ +--ca-cert=testpki-cacert.pem \ +--remote=pssl:0:127.0.0.1 \ +db + +while (true); do \ +ovsdb-client \ +--private-key=testpki-privkey.pem \ +--certificate=testpki-cert.pem \ +--ca-cert=testpki-cacert.pem \ +dump ssl:127.0.0.1:42067; \ +done + +console2: +watch -n 0.5 'cat /proc/$(pidof ovsdb-server)/status | grep VmSize' + +In console2 it was evidently seen ovsdb-server is constantly leaking memory. After a while +(i.e. after a certain number of reconnections) the OOM killer jumps out and kills ovsdb-server. + +Very similar situation was already noticed and described in +https://github.com/openvswitch/ovs-issues/issues/168. There, the problem pops up while connecting +controller to ovs-vswitchd daemon. + +Valgrind reports point to a problem in openssl library, however after studying openssl code for +a while I have found out the problem is actually in ovs. When connection through SSL channel is +taken place openssl library allocates memory for keeping track of certificate. Reference to this +memory works very similar as std::shared_ptr pointer in recent C++ dialects. i.e. when allocated +memory is referenced its reference counter is incremented and decremented after the memory is +derefered. When reference counter becomes zero allocated memory is automatically deallocated. + +In openssl library environment certificate is retrieved by calling SSL_get_peer_certificate() +where its reference counter is incremented. After retrieved certificate is not used any more its +reference counter must be decremented by calling X509_free(). If not, allocated memory is never +freed despite the ssl connection is properly closed. + +The problem was caused in stream-ssl.c in function ssl_connect(), which retrieves common peer name +by calling SSL_get_peer_certificate() function and without calling X509_free() function afterwards. + +Signed-off-by: Damijan Skvarc +Signed-off-by: Ben Pfaff +--- + lib/stream-ssl.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c +index 723fde9ad..078fcbc3a 100644 +--- a/lib/stream-ssl.c ++++ b/lib/stream-ssl.c +@@ -470,6 +470,7 @@ do_ca_cert_bootstrap(struct stream *stream) + static char * + get_peer_common_name(const struct ssl_stream *sslv) + { ++ char *peer_name = NULL; + X509 *peer_cert = SSL_get_peer_certificate(sslv->ssl); + if (!peer_cert) { + return NULL; +@@ -478,18 +479,18 @@ get_peer_common_name(const struct ssl_stream *sslv) + int cn_index = X509_NAME_get_index_by_NID(X509_get_subject_name(peer_cert), + NID_commonName, -1); + if (cn_index < 0) { +- return NULL; ++ goto error; + } + + X509_NAME_ENTRY *cn_entry = X509_NAME_get_entry( + X509_get_subject_name(peer_cert), cn_index); + if (!cn_entry) { +- return NULL; ++ goto error; + } + + ASN1_STRING *cn_data = X509_NAME_ENTRY_get_data(cn_entry); + if (!cn_data) { +- return NULL; ++ goto error; + } + + const char *cn; +@@ -499,7 +500,11 @@ get_peer_common_name(const struct ssl_stream *sslv) + #else + cn = (const char *)ASN1_STRING_get0_data(cn_data); + #endif +- return xstrdup(cn); ++ peer_name = xstrdup(cn); ++ ++error: ++ X509_free(peer_cert); ++ return peer_name; + } + + static int +-- +2.14.1 + + diff --git a/system-afxdp.at-Add-test-for-infinite-re-addition-of.patch b/system-afxdp.at-Add-test-for-infinite-re-addition-of.patch new file mode 100644 index 0000000..87534a0 --- /dev/null +++ b/system-afxdp.at-Add-test-for-infinite-re-addition-of.patch @@ -0,0 +1,74 @@ +From 1b3faafb1ee74ff5bc877bf0ef3097ce4d77f8ef Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Sat, 7 Dec 2019 15:46:18 +0100 +Subject: system-afxdp.at: Add test for infinite re-addition of failed ports. + +New file created for AF_XDP specific tests. + +Signed-off-by: Ilya Maximets +Acked-by: William Tu +--- + tests/automake.mk | 3 ++- + tests/system-afxdp-testsuite.at | 1 + + tests/system-afxdp.at | 24 ++++++++++++++++++++++++ + 3 files changed, 27 insertions(+), 1 deletion(-) + create mode 100644 tests/system-afxdp.at + +diff --git a/tests/automake.mk b/tests/automake.mk +index d6ab51732..657fd690e 100644 +--- a/tests/automake.mk ++++ b/tests/automake.mk +@@ -165,7 +165,8 @@ SYSTEM_USERSPACE_TESTSUITE_AT = \ + SYSTEM_AFXDP_TESTSUITE_AT = \ + tests/system-userspace-macros.at \ + tests/system-afxdp-testsuite.at \ +- tests/system-afxdp-macros.at ++ tests/system-afxdp-macros.at \ ++ tests/system-afxdp.at + + SYSTEM_TESTSUITE_AT = \ + tests/system-common-macros.at \ +diff --git a/tests/system-afxdp-testsuite.at b/tests/system-afxdp-testsuite.at +index 9b7a29066..01c1bf50c 100644 +--- a/tests/system-afxdp-testsuite.at ++++ b/tests/system-afxdp-testsuite.at +@@ -23,4 +23,5 @@ m4_include([tests/system-common-macros.at]) + m4_include([tests/system-userspace-macros.at]) + m4_include([tests/system-afxdp-macros.at]) + ++m4_include([tests/system-afxdp.at]) + m4_include([tests/system-traffic.at]) +diff --git a/tests/system-afxdp.at b/tests/system-afxdp.at +new file mode 100644 +index 000000000..e4451624f +--- /dev/null ++++ b/tests/system-afxdp.at +@@ -0,0 +1,24 @@ ++AT_BANNER([AF_XDP]) ++ ++AT_SETUP([AF_XDP - infinite re-addition of failed ports]) ++AT_KEYWORDS([afxdp infinite]) ++OVS_TRAFFIC_VSWITCHD_START() ++ ++AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ++ ++ADD_NAMESPACES(at_ns0, at_ns1) ++ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ++ ++AT_CHECK([ovs-vsctl del-port ovs-p0]) ++AT_CHECK([ovs-vsctl add-port br0 ovs-p0 -- \ ++ set interface ovs-p0 type=afxdp options:n_rxq=42], ++ [0], [], [stderr]) ++OVS_WAIT_UNTIL([grep "ovs-p0: could not set configuration" ovs-vswitchd.log]) ++sleep 5 ++AT_CHECK([grep "ovs-p0: could not set configuration" ovs-vswitchd.log | wc -l], ++ [0], [1 ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP(["/ovs-p0: Too big 'n_rxq'/d ++/ovs-p0: could not set configuration/d"]) ++AT_CLEANUP +-- +2.14.1 + + diff --git a/tc-Limit-the-max-action-number-to-16.patch b/tc-Limit-the-max-action-number-to-16.patch new file mode 100644 index 0000000..9b82f76 --- /dev/null +++ b/tc-Limit-the-max-action-number-to-16.patch @@ -0,0 +1,87 @@ +From 92f6c44a92cc3247db94fd5fe86bf7e5cb896a91 Mon Sep 17 00:00:00 2001 +From: Chris Mi +Date: Wed, 16 Oct 2019 11:37:14 +0300 +Subject: tc: Limit the max action number to 16 + +Currently, ovs supports to offload max TCA_ACT_MAX_PRIO(32) actions. +But net sched api has a limit of 4K message size which is not enough +for 32 actions when echo flag is set. + +After a lot of testing, we find that 16 actions is a reasonable number. +So in this commit, we introduced a new define to limit the max actions. + +Fixes: 0c70132cd288("tc: Make the actions order consistent") +Signed-off-by: Chris Mi +Reviewed-by: Roi Dayan +Signed-off-by: Simon Horman +--- + lib/netdev-offload-tc.c | 4 ++-- + lib/tc.c | 6 +++--- + lib/tc.h | 4 +++- + 3 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c +index 4cc044b4b..ad637b48c 100644 +--- a/lib/netdev-offload-tc.c ++++ b/lib/netdev-offload-tc.c +@@ -1303,8 +1303,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, + } + + NL_ATTR_FOR_EACH(nla, left, actions, actions_len) { +- if (flower.action_count >= TCA_ACT_MAX_PRIO) { +- VLOG_DBG_RL(&rl, "Can only support %d actions", flower.action_count); ++ if (flower.action_count >= TCA_ACT_MAX_NUM) { ++ VLOG_DBG_RL(&rl, "Can only support %d actions", TCA_ACT_MAX_NUM); + return EOPNOTSUPP; + } + action = &flower.actions[flower.action_count]; +diff --git a/lib/tc.c b/lib/tc.c +index 1eca35620..71418b3f3 100644 +--- a/lib/tc.c ++++ b/lib/tc.c +@@ -1362,7 +1362,7 @@ static int + nl_parse_flower_actions(struct nlattr **attrs, struct tc_flower *flower) + { + const struct nlattr *actions = attrs[TCA_FLOWER_ACT]; +- static struct nl_policy actions_orders_policy[TCA_ACT_MAX_PRIO + 1] = {}; ++ static struct nl_policy actions_orders_policy[TCA_ACT_MAX_NUM + 1] = {}; + struct nlattr *actions_orders[ARRAY_SIZE(actions_orders_policy)]; + const int max_size = ARRAY_SIZE(actions_orders_policy); + +@@ -1381,8 +1381,8 @@ nl_parse_flower_actions(struct nlattr **attrs, struct tc_flower *flower) + if (actions_orders[i]) { + int err; + +- if (flower->action_count >= TCA_ACT_MAX_PRIO) { +- VLOG_DBG_RL(&error_rl, "Can only support %d actions", flower->action_count); ++ if (flower->action_count >= TCA_ACT_MAX_NUM) { ++ VLOG_DBG_RL(&error_rl, "Can only support %d actions", TCA_ACT_MAX_NUM); + return EOPNOTSUPP; + } + err = nl_parse_single_action(actions_orders[i], flower); +diff --git a/lib/tc.h b/lib/tc.h +index 2e0f5e37a..b7c977a14 100644 +--- a/lib/tc.h ++++ b/lib/tc.h +@@ -197,6 +197,8 @@ enum tc_offloaded_state { + TC_OFFLOADED_STATE_NOT_IN_HW, + }; + ++#define TCA_ACT_MAX_NUM 16 ++ + struct tc_flower { + uint32_t handle; + uint32_t prio; +@@ -205,7 +207,7 @@ struct tc_flower { + struct tc_flower_key mask; + + int action_count; +- struct tc_action actions[TCA_ACT_MAX_PRIO]; ++ struct tc_action actions[TCA_ACT_MAX_NUM]; + + struct ovs_flow_stats stats; + uint64_t lastused; +-- +2.14.1 + + diff --git a/tests-Fix-indentation-in-userspace-packet-type-aware.patch b/tests-Fix-indentation-in-userspace-packet-type-aware.patch new file mode 100644 index 0000000..2256fa4 --- /dev/null +++ b/tests-Fix-indentation-in-userspace-packet-type-aware.patch @@ -0,0 +1,93 @@ +From 3d844530afca789a71e46076babf9cc09325c4bc Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Thu, 24 Oct 2019 12:28:50 +0000 +Subject: tests: Fix indentation in userspace packet type aware test. + +CC: Ben Pfaff +Fixes: 7be29a47576d ("ofproto-dpif: Remove tabs from output.") +Signed-off-by: Ilya Maximets +Acked-by: Ben Pfaff +--- + tests/system-userspace-packet-type-aware.at | 64 ++++++++++++++--------------- + 1 file changed, 32 insertions(+), 32 deletions(-) + +diff --git a/tests/system-userspace-packet-type-aware.at b/tests/system-userspace-packet-type-aware.at +index 24a7698ab..c2246316d 100644 +--- a/tests/system-userspace-packet-type-aware.at ++++ b/tests/system-userspace-packet-type-aware.at +@@ -252,39 +252,39 @@ AT_CHECK([ + + ### Verify datapath configuration + AT_CHECK([ +- ovs-appctl dpif/show | grep -v hit | sed 's/\t/ /g' ++ ovs-appctl dpif/show | grep -v hit + ], [0], [dnl +- br-in1: +- br-in1 65534/2: (tap) +- gre12 1020/14: (gre: remote_ip=10.0.0.2) +- gre12_l3 1021/14: (gre: packet_type=legacy_l3, remote_ip=10.0.0.2) +- gre13 1030/14: (gre: remote_ip=10.0.0.3) +- ovs-n1 10/15: (system) +- br-in2: +- br-in2 65534/3: (tap) +- gre21 2010/14: (gre: packet_type=ptap, remote_ip=20.0.0.1) +- gre23 2030/14: (gre: packet_type=ptap, remote_ip=20.0.0.3) +- ovs-n2 20/16: (system) +- br-in3: +- br-in3 65534/4: (tap) +- gre31 3010/14: (gre: remote_ip=30.0.0.1) +- gre32 3020/14: (gre: remote_ip=30.0.0.2) +- gre32_l3 3021/14: (gre: packet_type=legacy_l3, remote_ip=30.0.0.2) +- ovs-n3 30/17: (system) +- br-p1: +- br-p1 65534/5: (tap) +- p1-0 2/8: (system) +- br-p2: +- br-p2 65534/6: (tap) +- p2-0 2/9: (system) +- br-p3: +- br-p3 65534/7: (tap) +- p3-0 2/10: (system) +- br0: +- br0 65534/1: (tap) +- p0-1 10/11: (system) +- p0-2 20/12: (system) +- p0-3 30/13: (system) ++ br-in1: ++ br-in1 65534/2: (tap) ++ gre12 1020/14: (gre: remote_ip=10.0.0.2) ++ gre12_l3 1021/14: (gre: packet_type=legacy_l3, remote_ip=10.0.0.2) ++ gre13 1030/14: (gre: remote_ip=10.0.0.3) ++ ovs-n1 10/15: (system) ++ br-in2: ++ br-in2 65534/3: (tap) ++ gre21 2010/14: (gre: packet_type=ptap, remote_ip=20.0.0.1) ++ gre23 2030/14: (gre: packet_type=ptap, remote_ip=20.0.0.3) ++ ovs-n2 20/16: (system) ++ br-in3: ++ br-in3 65534/4: (tap) ++ gre31 3010/14: (gre: remote_ip=30.0.0.1) ++ gre32 3020/14: (gre: remote_ip=30.0.0.2) ++ gre32_l3 3021/14: (gre: packet_type=legacy_l3, remote_ip=30.0.0.2) ++ ovs-n3 30/17: (system) ++ br-p1: ++ br-p1 65534/5: (tap) ++ p1-0 2/8: (system) ++ br-p2: ++ br-p2 65534/6: (tap) ++ p2-0 2/9: (system) ++ br-p3: ++ br-p3 65534/7: (tap) ++ p3-0 2/10: (system) ++ br0: ++ br0 65534/1: (tap) ++ p0-1 10/11: (system) ++ p0-2 20/12: (system) ++ p0-3 30/13: (system) + ]) + + ### Test L3 forwarding flows +-- +2.14.1 + + diff --git a/travis-Drop-MD-related-workaround-for-sparse.patch b/travis-Drop-MD-related-workaround-for-sparse.patch new file mode 100644 index 0000000..7a0ee4f --- /dev/null +++ b/travis-Drop-MD-related-workaround-for-sparse.patch @@ -0,0 +1,36 @@ +From e92cfbf246df1b0cd48e17de75edcb724efe5620 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Thu, 26 Sep 2019 12:03:09 +0300 +Subject: travis: Drop -MD related workaround for sparse. + +The issue was fixed in upstream sparse by the following commit: +d90c0838c101 ("cgcc: fix wrong processing of -MD & -MMD") + +This patch is required to fix our travis build. + +Signed-off-by: Ilya Maximets +Acked-by: Ian Stokes +--- + .travis/linux-prepare.sh | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/.travis/linux-prepare.sh b/.travis/linux-prepare.sh +index 65348c9f9..70fd98f71 100755 +--- a/.travis/linux-prepare.sh ++++ b/.travis/linux-prepare.sh +@@ -9,11 +9,6 @@ set -ev + # linking against it fails. + git clone git://git.kernel.org/pub/scm/devel/sparse/sparse.git + cd sparse +-# Commit bb1bf748580d ("cgcc: gendeps for -MM, -MD & -MMD too") makes +-# sparse ignore almost all source files, because 'make' uses '-MD' to +-# generate dependencies as a side effect within compilation commands. +-git revert bb1bf748580d --no-commit +-git diff HEAD + make -j4 HAVE_LLVM= install + cd .. + +-- +2.14.1 + + diff --git a/trigger-Free-leaked-ovsdb_schema.patch b/trigger-Free-leaked-ovsdb_schema.patch new file mode 100644 index 0000000..44e0347 --- /dev/null +++ b/trigger-Free-leaked-ovsdb_schema.patch @@ -0,0 +1,51 @@ +From e345c75b4413e6bdbc0d47df5da35bfd426d8788 Mon Sep 17 00:00:00 2001 +From: Yifeng Sun +Date: Wed, 11 Sep 2019 14:18:31 -0700 +Subject: trigger: Free leaked ovsdb_schema + +Valgrind reported: + +1925: schema conversion online - standalone + +==10884== 689 (56 direct, 633 indirect) bytes in 1 blocks are definitely lost in loss record 384 of 420 +==10884== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==10884== by 0x44A592: xcalloc (util.c:121) +==10884== by 0x40E2EC: ovsdb_schema_create (ovsdb.c:41) +==10884== by 0x40E688: ovsdb_schema_from_json (ovsdb.c:217) +==10884== by 0x416C6F: ovsdb_trigger_try (trigger.c:246) +==10884== by 0x40D4DE: ovsdb_jsonrpc_trigger_create (jsonrpc-server.c:1119) +==10884== by 0x40D4DE: ovsdb_jsonrpc_session_got_request (jsonrpc-server.c:986) +==10884== by 0x40D4DE: ovsdb_jsonrpc_session_run (jsonrpc-server.c:556) +==10884== by 0x40D4DE: ovsdb_jsonrpc_session_run_all (jsonrpc-server.c:586) +==10884== by 0x40D4DE: ovsdb_jsonrpc_server_run (jsonrpc-server.c:401) +==10884== by 0x406A6E: main_loop (ovsdb-server.c:209) +==10884== by 0x406A6E: main (ovsdb-server.c:460) + +'new_schema' should also be freed when there is no error. +This patch fixes it. + +Acked-by: William Tu +Signed-off-by: Yifeng Sun +Signed-off-by: Ben Pfaff +--- + ovsdb/trigger.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ovsdb/trigger.c b/ovsdb/trigger.c +index 6f4ed96b0..7e62e90ae 100644 +--- a/ovsdb/trigger.c ++++ b/ovsdb/trigger.c +@@ -254,8 +254,8 @@ ovsdb_trigger_try(struct ovsdb_trigger *t, long long int now) + if (!error) { + error = ovsdb_convert(t->db, new_schema, &newdb); + } ++ ovsdb_schema_destroy(new_schema); + if (error) { +- ovsdb_schema_destroy(new_schema); + trigger_convert_error(t, error); + return false; + } +-- +2.14.1 + + diff --git a/vswitch.xml-Fix-column-for-xdpmode.patch b/vswitch.xml-Fix-column-for-xdpmode.patch new file mode 100644 index 0000000..962b673 --- /dev/null +++ b/vswitch.xml-Fix-column-for-xdpmode.patch @@ -0,0 +1,33 @@ +From 7accd13028f1b7d7d6cdd50ffec2657142832527 Mon Sep 17 00:00:00 2001 +From: Ilya Maximets +Date: Tue, 5 Nov 2019 21:54:08 +0100 +Subject: vswitch.xml: Fix column for xdpmode. + +'xdpmode' is part of 'options', not the 'other_config'. + +CC: William Tu +Fixes: 0de1b425962d ("netdev-afxdp: add new netdev type for AF_XDP.") +Signed-off-by: Ilya Maximets +Acked-by: Ben Pfaff +Signed-off-by: William Tu +--- + vswitchd/vswitch.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml +index 027aee2f5..69dbe460f 100644 +--- a/vswitchd/vswitch.xml ++++ b/vswitchd/vswitch.xml +@@ -3107,7 +3107,7 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ +

+ + +- +

+-- +2.14.1 + + -- Gitee