From ee8143d3f47b1444c3be2706b589a32010d0e95e39a83968e23566fd12c87068 Mon Sep 17 00:00:00 2001 From: Reinhard Max Date: Thu, 6 Apr 2023 09:47:29 +0000 Subject: [PATCH] Accepting request 1077608 from home:dpitchumani:branches:openSUSE:Factory Description: - Update OVS to version v3.1.0 and OVN to version v23.03.0 Actions: - submit home:dpitchumani:branches:openSUSE:Factory/openvswitch => netowkr/openvswitch Features: - ovs-vswitchd now detects changes in CPU affinity and adjusts the number of handler and revalidator threads if necessary. - AF_XDP: * Added support for building with libxdp and libbpf >= 0.7. * Support for AF_XDP is now enabled by default if all dependencies are available at the build time. Use --disable-afxdp to disable. Use --enable-afxdp to fail the build if dependencies are not present. - ovs-appctl: * "ovs-appctl ofproto/trace" command can now display port names with the "--names" option. - OVSDB-IDL: * Add the support to specify the persistent uuid for row insert in both C and Python IDLs. - Windows: * Conntrack IPv6 fragment support. - DPDK: * Add support for DPDK 22.11.1. - For the QoS max-rate and STP/RSTP path-cost configuration OVS now assumes 10 Gbps link speed by default in case the actual link speed cannot be determined. Previously it was 10 Mbps. Values can still be overridden by specifying 'max-rate' or '[r]stp-path-cost' accordingly. - OpenFlow: * New OpenFlow extension NXT_CT_FLUSH to flush connections matching the specified fields. - ovs-ctl: * New option '--dump-hugepages' to include hugepages in core dumps. This can assist with postmortem analysis involving DPDK, but may also produce significantly larger core dump files. - ovs-dpctl and 'ovs-appctl dpctl/' commands: * 'flush-conntrack' is now capable of handling partial 5-tuple, with additional optional parameter to specify the reply direction. - ovs-ofctl: * New command 'flush-conntrack' that accepts zone and 5-tuple (or partial 5-tuple) for both directions. - Support for travis-ci.org based continuous integration builds has been dropped. - Userspace datapath: * Add '-secs' argument to appctl 'dpif-netdev/pmd-rxq-show' to show the pmd usage of an Rx queue over a configurable time period. * Add new experimental PMD load based sleeping feature. PMD threads can request to sleep up to a user configured 'pmd-maxsleep' value under low load conditions. -For more details, check https://github.com/openvswitch/ovs/blob/v3.1.0/NEWS -Includes secrity fix for CVE-2022-4338 (bsc#1206580) and CVE-2022-4337 (bsc#1206581) - OVN package is not included as new version with API chnages are not yet released. - Removed upstreamed patches, * 0001-Replace-deprecated-var-run-with-run.patch * openvswitch-CVE-2021-36980.patch - Added ovsb tool install patch, * install-ovsdb-tools.patch OBS-URL: https://build.opensuse.org/request/show/1077608 OBS-URL: https://build.opensuse.org/package/show/network/openvswitch?expand=0&rev=238 --- ...-change-permissions-of-dev-hugepages.patch | 10 +- ...envswitch-as-openvswitch-openvswitch.patch | 18 +- 0001-Run-ovn-as-openvswitch-openvswitch.patch | 49 + ...-double-hash-for-OVS_USER_ID-comment.patch | 11 +- ...ngswan-for-openvswitch-ipsec-service.patch | 16 +- 0001-m4-Test-avx512-for-x86-only.patch | 46 - ...-build-Seperated-common-used-headers.patch | 45798 ---------------- ...d9693c8b49055389559187fe74eddb619746.patch | 355 - install-ovsdb-tools.patch | 11 +- ...h-2.17.2-Fix-tests-with-GNU-grep-3.8.patch | 468 - openvswitch-2.17.2.tar.gz | 3 - openvswitch-3.1.0.tar.gz | 3 + openvswitch.changes | 57 + openvswitch.spec | 924 +- ovn-23.03.0.tar.gz | 3 + 15 files changed, 936 insertions(+), 46836 deletions(-) rename Don-t-change-permissions-of-dev-hugepages.patch => 0001-Don-t-change-permissions-of-dev-hugepages.patch (88%) rename Run-openvswitch-as-openvswitch-openvswitch.patch => 0001-Run-openvswitch-as-openvswitch-openvswitch.patch (78%) create mode 100644 0001-Run-ovn-as-openvswitch-openvswitch.patch rename Use-double-hash-for-OVS_USER_ID-comment.patch => 0001-Use-double-hash-for-OVS_USER_ID-comment.patch (75%) rename Use-strongswan-for-openvswitch-ipsec-service.patch => 0001-Use-strongswan-for-openvswitch-ipsec-service.patch (56%) delete mode 100644 0001-m4-Test-avx512-for-x86-only.patch delete mode 100644 0002-build-Seperated-common-used-headers.patch delete mode 100644 a77ad9693c8b49055389559187fe74eddb619746.patch delete mode 100644 openvswitch-2.17.2-Fix-tests-with-GNU-grep-3.8.patch delete mode 100644 openvswitch-2.17.2.tar.gz create mode 100644 openvswitch-3.1.0.tar.gz create mode 100644 ovn-23.03.0.tar.gz diff --git a/Don-t-change-permissions-of-dev-hugepages.patch b/0001-Don-t-change-permissions-of-dev-hugepages.patch similarity index 88% rename from Don-t-change-permissions-of-dev-hugepages.patch rename to 0001-Don-t-change-permissions-of-dev-hugepages.patch index 1084577..18f9600 100644 --- a/Don-t-change-permissions-of-dev-hugepages.patch +++ b/0001-Don-t-change-permissions-of-dev-hugepages.patch @@ -6,12 +6,11 @@ Subject: [PATCH 1/2] Don't change permissions of /dev/hugepages For SLES/openSUSE, don't change permissions of /dev/hugepages as that is a system path. Sysadmin shoudl mount hugepages on a path and permission of his choosing if OVS either manually or via hugeadm. ---- - rhel/usr_lib_systemd_system_ovs-vswitchd.service.in | 4 ---- - 1 file changed, 4 deletions(-) + +Updated 2023-02-26 for version 3.1.0 diff --git a/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in b/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in -index ff43dae96..08355d950 100644 +index 6d021618b..71c49dc59 100644 --- a/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in +++ b/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in @@ -16,10 +16,6 @@ EnvironmentFile=/etc/openvswitch/default.conf @@ -25,6 +24,3 @@ index ff43dae96..08355d950 100644 ExecStart=/usr/share/openvswitch/scripts/ovs-ctl \ --no-ovsdb-server --no-monitor --system-id=random \ ${OVS_USER_OPT} \ --- -2.16.4 - diff --git a/Run-openvswitch-as-openvswitch-openvswitch.patch b/0001-Run-openvswitch-as-openvswitch-openvswitch.patch similarity index 78% rename from Run-openvswitch-as-openvswitch-openvswitch.patch rename to 0001-Run-openvswitch-as-openvswitch-openvswitch.patch index e03f9cc..8883ca4 100644 --- a/Run-openvswitch-as-openvswitch-openvswitch.patch +++ b/0001-Run-openvswitch-as-openvswitch-openvswitch.patch @@ -7,13 +7,11 @@ Change default run configuration to unprivilieged user openvswitch and group openvswitch. Expect any further customization from user in sysconfig/openvswitch, including setting it back to privileged root:root configuration. ---- - rhel/etc_logrotate.d_openvswitch | 2 +- - rhel/etc_openvswitch_default.conf | 3 +-- - 2 files changed, 2 insertions(+), 3 deletions(-) + +Updated 2023-02-26 for version 3.1.0 diff --git a/rhel/etc_logrotate.d_openvswitch b/rhel/etc_logrotate.d_openvswitch -index f4302ffbc..eaf1fd5bf 100644 +index c0f476744..fa6303873 100644 --- a/rhel/etc_logrotate.d_openvswitch +++ b/rhel/etc_logrotate.d_openvswitch @@ -6,7 +6,7 @@ @@ -26,16 +24,12 @@ index f4302ffbc..eaf1fd5bf 100644 compress sharedscripts diff --git a/rhel/etc_openvswitch_default.conf b/rhel/etc_openvswitch_default.conf -index c74417db6..20d1f5f54 100644 +index c74417db6..569ca95de 100644 --- a/rhel/etc_openvswitch_default.conf +++ b/rhel/etc_openvswitch_default.conf -@@ -1,5 +1,4 @@ - # DO NOT EDIT THIS FILE +@@ -2,4 +2,4 @@ # The following is the *default* configuration for the openvswitch user ID. --# This is for backward compatibility. + # This is for backward compatibility. -OVS_USER_ID="root:root" +OVS_USER_ID="openvswitch:openvswitch" --- -2.16.4 - diff --git a/0001-Run-ovn-as-openvswitch-openvswitch.patch b/0001-Run-ovn-as-openvswitch-openvswitch.patch new file mode 100644 index 0000000..916e677 --- /dev/null +++ b/0001-Run-ovn-as-openvswitch-openvswitch.patch @@ -0,0 +1,49 @@ +diff --git a/rhel/etc_logrotate.d_ovn b/rhel/etc_logrotate.d_ovn +index a351ec303..4b26333fc 100644 +--- a/rhel/etc_logrotate.d_ovn ++++ b/rhel/etc_logrotate.d_ovn +@@ -6,7 +6,7 @@ + # without warranty of any kind. + + /var/log/ovn/*.log { +- su root root ++ su openvswitch openvswitch + daily + compress + sharedscripts +diff --git a/rhel/usr_lib_systemd_system_ovn-controller-vtep.service b/rhel/usr_lib_systemd_system_ovn-controller-vtep.service +index c6601cb46..48f6e3992 100644 +--- a/rhel/usr_lib_systemd_system_ovn-controller-vtep.service ++++ b/rhel/usr_lib_systemd_system_ovn-controller-vtep.service +@@ -35,6 +35,7 @@ After=openvswitch.service + [Service] + Type=simple + Restart=on-failure ++Environment=OVN_USER_ID=openvswitch:openvswitch + Environment=OVS_RUNDIR=%t/openvswitch + Environment=OVN_RUNDIR=%t/ovn + Environment=OVN_DB=unix:%t/ovn/ovnsb_db.sock +diff --git a/rhel/usr_lib_systemd_system_ovn-controller.service b/rhel/usr_lib_systemd_system_ovn-controller.service +index 15d0ac853..c602760f1 100644 +--- a/rhel/usr_lib_systemd_system_ovn-controller.service ++++ b/rhel/usr_lib_systemd_system_ovn-controller.service +@@ -23,6 +23,7 @@ After=openvswitch.service + Type=forking + PIDFile=/var/run/ovn/ovn-controller.pid + Restart=on-failure ++Environment=OVN_USER_ID=openvswitch:openvswitch + Environment=OVN_RUNDIR=%t/ovn OVS_RUNDIR=%t/openvswitch + EnvironmentFile=-/etc/sysconfig/ovn + EnvironmentFile=-/etc/sysconfig/ovn-controller +diff --git a/rhel/usr_lib_systemd_system_ovn-northd.service b/rhel/usr_lib_systemd_system_ovn-northd.service +index 6c4c6621c..d74196a49 100644 +--- a/rhel/usr_lib_systemd_system_ovn-northd.service ++++ b/rhel/usr_lib_systemd_system_ovn-northd.service +@@ -20,6 +20,7 @@ After=syslog.target + [Service] + Type=oneshot + RemainAfterExit=yes ++Environment=OVN_USER_ID=openvswitch:openvswitch + Environment=OVN_RUNDIR=%t/ovn OVN_DBDIR=/var/lib/ovn + EnvironmentFile=-/etc/sysconfig/ovn + EnvironmentFile=-/etc/sysconfig/ovn-northd diff --git a/Use-double-hash-for-OVS_USER_ID-comment.patch b/0001-Use-double-hash-for-OVS_USER_ID-comment.patch similarity index 75% rename from Use-double-hash-for-OVS_USER_ID-comment.patch rename to 0001-Use-double-hash-for-OVS_USER_ID-comment.patch index 3d546c6..d0996c3 100644 --- a/Use-double-hash-for-OVS_USER_ID-comment.patch +++ b/0001-Use-double-hash-for-OVS_USER_ID-comment.patch @@ -3,12 +3,10 @@ From: =?UTF-8?q?Jaime=20Caama=C3=B1o=20Ruiz?= Date: Mon, 15 Jun 2020 15:15:53 +0200 Subject: [PATCH] Use double hash for OVS_USER_ID comment ---- - rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) +Updated 2023-02-26 for version 3.1.0 diff --git a/rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template b/rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template -index c467d02db..10b841679 100644 +index c467d02db..58c0e4797 100644 --- a/rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template +++ b/rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template @@ -28,4 +28,4 @@ @@ -16,7 +14,4 @@ index c467d02db..10b841679 100644 # Uncomment and set the OVS User/Group value -#OVS_USER_ID="openvswitch:openvswitch" -+## OVS_USER_ID="openvswitch:openvswitch" --- -2.26.1 - ++##OVS_USER_ID="openvswitch:openvswitch" diff --git a/Use-strongswan-for-openvswitch-ipsec-service.patch b/0001-Use-strongswan-for-openvswitch-ipsec-service.patch similarity index 56% rename from Use-strongswan-for-openvswitch-ipsec-service.patch rename to 0001-Use-strongswan-for-openvswitch-ipsec-service.patch index 0835760..604710f 100644 --- a/Use-strongswan-for-openvswitch-ipsec-service.patch +++ b/0001-Use-strongswan-for-openvswitch-ipsec-service.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Use strongswan for openvswitch-ipsec service Since libreswan is not packaged for Leap/SLES, use strongswan for the time being. ---- - rhel/usr_lib_systemd_system_openvswitch-ipsec.service | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) -diff -Nur openvswitch-2.17.0/rhel/usr_lib_systemd_system_openvswitch-ipsec.service new/rhel/usr_lib_systemd_system_openvswitch-ipsec.service ---- openvswitch-2.17.0/rhel/usr_lib_systemd_system_openvswitch-ipsec.service 2022-02-17 23:15:55.257680736 +0100 -+++ new/rhel/usr_lib_systemd_system_openvswitch-ipsec.service 2022-02-26 02:22:12.429785364 +0100 -@@ -7,7 +7,7 @@ +Updated 2023-02-26 for version 3.1.0 + +diff --git a/rhel/usr_lib_systemd_system_openvswitch-ipsec.service b/rhel/usr_lib_systemd_system_openvswitch-ipsec.service +index 92dad44f9..ec86874cb 100644 +--- a/rhel/usr_lib_systemd_system_openvswitch-ipsec.service ++++ b/rhel/usr_lib_systemd_system_openvswitch-ipsec.service +@@ -7,7 +7,7 @@ After=openvswitch.service Type=forking PIDFile=/run/openvswitch/ovs-monitor-ipsec.pid ExecStart=/usr/share/openvswitch/scripts/ovs-ctl \ - --ike-daemon=libreswan start-ovs-ipsec + --ike-daemon=strongswan start-ovs-ipsec ExecStop=/usr/share/openvswitch/scripts/ovs-ctl stop-ovs-ipsec - + [Install] diff --git a/0001-m4-Test-avx512-for-x86-only.patch b/0001-m4-Test-avx512-for-x86-only.patch deleted file mode 100644 index 76ce0ff..0000000 --- a/0001-m4-Test-avx512-for-x86-only.patch +++ /dev/null @@ -1,46 +0,0 @@ -From edf699ec6404da3612b58aab85d7da12f0dc9733 Mon Sep 17 00:00:00 2001 -From: Cheng Li -Date: Fri, 16 Sep 2022 09:56:18 +0000 -Subject: [PATCH] m4: Test avx512 for x86 only. - -'as' command of arm version may don't support option '--64', this -patch is to move the avx512 test into x86 branch to avoid this. - -Fixes: 352b6c7116cd ("dpif-lookup: add avx512 gather implementation.") -Tested-by: Harry van Haaren -Signed-off-by: Cheng Li -Signed-off-by: Ilya Maximets ---- - m4/openvswitch.m4 | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4 -index 21808483e..09134feca 100644 ---- a/m4/openvswitch.m4 -+++ b/m4/openvswitch.m4 -@@ -436,8 +436,8 @@ AC_DEFUN([OVS_CHECK_BINUTILS_AVX512], - mkdir -p build-aux - OBJFILE=build-aux/binutils_avx512_check.o - GATHER_PARAMS='0x8(,%ymm1,1),%ymm0{%k2}' -- echo "vpgatherqq $GATHER_PARAMS" | as --64 -o $OBJFILE - - if ($CC -dumpmachine | grep x86_64) >/dev/null 2>&1; then -+ echo "vpgatherqq $GATHER_PARAMS" | as --64 -o $OBJFILE - - if (objdump -d --no-show-raw-insn $OBJFILE | grep -q $GATHER_PARAMS) >/dev/null 2>&1; then - ovs_cv_binutils_avx512_good=yes - else -@@ -446,11 +446,11 @@ AC_DEFUN([OVS_CHECK_BINUTILS_AVX512], - dnl and causing zmm usage with buggy binutils versions. - CFLAGS="$CFLAGS -mno-avx512f" - fi -+ rm $OBJFILE - else - dnl non x86_64 architectures don't have avx512, so not affected - ovs_cv_binutils_avx512_good=no - fi]) -- rm $OBJFILE - if test "$ovs_cv_binutils_avx512_good" = yes; then - AC_DEFINE([HAVE_LD_AVX512_GOOD], [1], - [Define to 1 if binutils correctly supports AVX512.]) --- -2.37.3 - diff --git a/0002-build-Seperated-common-used-headers.patch b/0002-build-Seperated-common-used-headers.patch deleted file mode 100644 index 5824657..0000000 --- a/0002-build-Seperated-common-used-headers.patch +++ /dev/null @@ -1,45798 +0,0 @@ -From 8e62dcacc834a2318cb69533f4f83d32bc950fd4 Mon Sep 17 00:00:00 2001 -From: Ferdinand Thiessen -Date: Mon, 28 Feb 2022 15:32:27 +0100 -Subject: [PATCH 2/2] build: Seperated common used headers - ---- - Makefile.am | 2 +- - build-aux/extract-odp-netlink-h | 9 + - build-aux/extract-odp-netlink-macros-h | 6 + - datapath/conntrack.c | 2 +- - datapath/conntrack.h | 2 +- - datapath/datapath.c | 2 +- - datapath/datapath.h | 2 +- - datapath/flow.c | 2 +- - datapath/flow_netlink.c | 2 +- - datapath/flow_netlink.h | 2 +- - datapath/flow_table.c | 2 +- - datapath/flow_table.h | 2 +- - datapath/meter.h | 2 +- - include/automake.mk | 1 + - include/internal/automake.mk | 77 +++ - {lib => include/internal}/bitmap.h | 2 +- - {lib => include/internal}/bundle.h | 0 - {lib => include/internal}/byte-order.h | 0 - {lib => include/internal}/classifier.h | 8 +- - {lib => include/internal}/cmap.h | 4 +- - {lib => include/internal}/colors.h | 0 - {lib => include/internal}/command-line.h | 0 - {lib => include/internal}/coverage.h | 2 +- - {lib => include/internal}/crc32c.h | 0 - {lib => include/internal}/csum.h | 0 - {lib => include/internal}/daemon.h | 0 - {lib => include/internal}/db-ctl-base.h | 0 - {lib => include/internal}/dhcp.h | 4 +- - {lib => include/internal}/dhparams.h | 0 - {lib => include/internal}/dirs.h | 0 - {lib => include/internal}/dp-packet.h | 10 +- - {lib => include/internal}/fatal-signal.h | 0 - {lib => include/internal}/flow.h | 10 +- - {lib => include/internal}/hash-aarch64.h | 0 - {lib => include/internal}/hash.h | 4 +- - {lib => include/internal}/hindex.h | 2 +- - {lib => include/internal}/hmapx.h | 0 - {lib => include/internal}/id-pool.h | 0 - {lib => include/internal}/jsonrpc.h | 0 - {lib => include/internal}/latch.h | 2 +- - {lib => include/internal}/mcast-snooping.h | 10 +- - {lib => include/internal}/memory.h | 0 - {lib => include/internal}/netdev-afxdp.h | 0 - {lib => include/internal}/netdev-dpdk.h | 0 - {lib => include/internal}/netdev.h | 4 +- - {lib => include/internal}/netlink-protocol.h | 2 +- - {lib => include/internal}/netlink.h | 2 +- - {lib => include/internal}/nx-match.h | 2 +- - {lib => include/internal}/ovs-atomic-c++.h | 0 - {lib => include/internal}/ovs-atomic-c11.h | 0 - {lib => include/internal}/ovs-atomic-clang.h | 2 +- - .../internal}/ovs-atomic-flag-gcc4.7+.h | 0 - {lib => include/internal}/ovs-atomic-gcc4+.h | 2 +- - .../internal}/ovs-atomic-gcc4.7+.h | 2 +- - {lib => include/internal}/ovs-atomic-i586.h | 0 - {lib => include/internal}/ovs-atomic-locked.c | 6 +- - {lib => include/internal}/ovs-atomic-locked.h | 0 - {lib => include/internal}/ovs-atomic-msvc.h | 0 - .../internal}/ovs-atomic-pthreads.h | 2 +- - {lib => include/internal}/ovs-atomic-x86_64.h | 0 - {lib => include/internal}/packets.h | 12 +- - {lib => include/internal}/process.h | 0 - {lib => include/internal}/pvector.h | 4 +- - {lib => include/internal}/random.h | 0 - {lib => include/internal}/rculist.h | 4 +- - {lib => include/internal}/seq.h | 2 +- - {lib => include/internal}/simap.h | 0 - {lib => include/internal}/skiplist.h | 0 - {lib => include/internal}/smap.h | 2 +- - {lib => include/internal}/socket-util.h | 0 - {lib => include/internal}/sort.h | 0 - {lib => include/internal}/sset.h | 2 +- - {lib => include/internal}/stopwatch.h | 0 - {lib => include/internal}/stream-ssl.h | 0 - {lib => include/internal}/stream.h | 4 +- - {lib => include/internal}/svec.h | 0 - {lib => include/internal}/table.h | 0 - {lib => include/internal}/timer.h | 4 +- - {lib => include/internal}/timeval.h | 2 +- - .../internal/tun-metadata-private.h | 2 +- - {lib => include/internal}/unaligned.h | 4 +- - {lib => include/internal}/unixctl.h | 0 - include/internal/util.h | 603 ++++++++++++++++++ - {lib => include/internal}/uuid.h | 0 - {lib => include/internal}/versions.h | 2 +- - include/openvswitch/automake.mk | 16 + - {lib => include/openvswitch}/ovs-atomic.h | 30 +- - {lib => include/openvswitch}/ovs-numa.h | 8 + - {lib => include/openvswitch}/ovs-rcu.h | 10 +- - {lib => include/openvswitch}/ovs-thread.h | 14 +- - .../openvswitch}/ovsdb-condition.h | 8 + - {lib => include/openvswitch}/ovsdb-cs.h | 10 +- - {lib => include/openvswitch}/ovsdb-data.h | 4 +- - {lib => include/openvswitch}/ovsdb-error.h | 8 + - .../openvswitch}/ovsdb-idl-provider.h | 12 +- - {lib => include/openvswitch}/ovsdb-idl.h | 8 +- - {lib => include/openvswitch}/ovsdb-map-op.h | 2 +- - {lib => include/openvswitch}/ovsdb-parser.h | 12 +- - {lib => include/openvswitch}/ovsdb-set-op.h | 2 +- - {lib => include/openvswitch}/ovsdb-types.h | 2 +- - include/sparse/automake.mk | 10 +- - include/windows/netinet/icmp6.h | 2 +- - include/windows/netinet/ip6.h | 2 +- - lib/aes128.c | 2 +- - lib/async-append-aio.c | 4 +- - lib/async-append-null.c | 2 +- - lib/automake.mk | 16 - - lib/backtrace.c | 2 +- - lib/bfd.c | 30 +- - lib/bfd.h | 2 +- - lib/bundle.c | 8 +- - lib/byteq.c | 2 +- - lib/ccmap.c | 12 +- - lib/ccmap.h | 4 +- - lib/cfm.c | 26 +- - lib/cfm.h | 2 +- - lib/classifier-private.h | 8 +- - lib/classifier.c | 8 +- - lib/cmap.c | 14 +- - lib/colors.c | 4 +- - lib/command-line.c | 8 +- - lib/connectivity.c | 4 +- - lib/conntrack-icmp.c | 2 +- - lib/conntrack-other.c | 2 +- - lib/conntrack-private.h | 8 +- - lib/conntrack-tcp.c | 6 +- - lib/conntrack.c | 20 +- - lib/conntrack.h | 12 +- - lib/coverage.c | 12 +- - lib/crc32c.c | 4 +- - lib/csum.c | 4 +- - lib/ct-dpif.h | 2 +- - lib/daemon-unix.c | 18 +- - lib/daemon-windows.c | 8 +- - lib/daemon.c | 6 +- - lib/db-ctl-base.c | 23 +- - lib/dhparams.c | 2 +- - lib/dirs.c.in | 6 +- - lib/dns-resolve.c | 4 +- - lib/dp-packet.c | 8 +- - lib/dpctl.c | 23 +- - lib/dpdk-stub.c | 4 +- - lib/dpdk.c | 18 +- - lib/dpif-netdev-avx512.c | 4 +- - lib/dpif-netdev-extract-avx512.c | 2 +- - lib/dpif-netdev-extract-study.c | 2 +- - lib/dpif-netdev-lookup-avx512-gather.c | 6 +- - lib/dpif-netdev-lookup-generic.c | 14 +- - lib/dpif-netdev-perf.c | 6 +- - lib/dpif-netdev-perf.h | 8 +- - lib/dpif-netdev-private-dpcls.h | 2 +- - lib/dpif-netdev-private-dpif.c | 2 +- - lib/dpif-netdev-private-extract.c | 8 +- - lib/dpif-netdev-private-flow.h | 2 +- - lib/dpif-netdev-private-thread.h | 2 +- - lib/dpif-netdev.c | 44 +- - lib/dpif-netdev.h | 4 +- - lib/dpif-netlink-rtnl.h | 2 +- - lib/dpif-netlink.c | 20 +- - lib/dpif-netlink.h | 2 +- - lib/dpif-provider.h | 2 +- - lib/dpif.c | 22 +- - lib/dpif.h | 10 +- - lib/dummy.c | 2 +- - lib/dynamic-string.c | 4 +- - lib/entropy.c | 4 +- - lib/fat-rwlock.c | 4 +- - lib/fat-rwlock.h | 2 +- - lib/fatal-signal.c | 10 +- - lib/flow.c | 28 +- - lib/getopt_long.c | 2 +- - lib/getrusage-windows.c | 2 +- - lib/guarded-list.h | 2 +- - lib/hash.c | 4 +- - lib/heap.c | 2 +- - lib/hindex.c | 4 +- - lib/hmap.c | 6 +- - lib/hmapx.c | 4 +- - lib/id-fpool.c | 2 +- - lib/id-pool.c | 4 +- - lib/if-notifier-bsd.c | 2 +- - lib/if-notifier.c | 2 +- - lib/ipf.c | 12 +- - lib/ipf.h | 2 +- - lib/jhash.c | 2 +- - lib/jhash.h | 2 +- - lib/json.c | 6 +- - lib/jsonrpc.c | 12 +- - lib/lacp.c | 18 +- - lib/lacp.h | 2 +- - lib/latch-unix.c | 4 +- - lib/latch-windows.c | 4 +- - lib/learn.c | 8 +- - lib/learning-switch.c | 12 +- - lib/lldp/lldp.c | 4 +- - lib/lldp/lldpd-structs.c | 2 +- - lib/lldp/lldpd-structs.h | 2 +- - lib/lldp/lldpd.c | 4 +- - lib/lldp/lldpd.h | 4 +- - lib/lockfile.c | 10 +- - lib/mac-learning.c | 12 +- - lib/mac-learning.h | 8 +- - lib/match.c | 10 +- - lib/mcast-snooping.c | 16 +- - lib/memory.c | 8 +- - lib/meta-flow.c | 22 +- - lib/mpsc-queue.c | 2 +- - lib/mpsc-queue.h | 2 +- - lib/multipath.c | 8 +- - lib/namemap.c | 2 +- - lib/netdev-afxdp-pool.c | 2 +- - lib/netdev-afxdp-pool.h | 2 +- - lib/netdev-afxdp.c | 16 +- - lib/netdev-bsd.c | 16 +- - lib/netdev-dpdk.c | 34 +- - lib/netdev-dummy.c | 18 +- - lib/netdev-linux-private.h | 8 +- - lib/netdev-linux.c | 28 +- - lib/netdev-native-tnl.c | 16 +- - lib/netdev-native-tnl.h | 6 +- - lib/netdev-offload-dpdk.c | 8 +- - lib/netdev-offload-provider.h | 4 +- - lib/netdev-offload-tc.c | 8 +- - lib/netdev-offload.c | 26 +- - lib/netdev-offload.h | 8 +- - lib/netdev-provider.h | 12 +- - lib/netdev-vport-private.h | 4 +- - lib/netdev-vport.c | 20 +- - lib/netdev-windows.c | 10 +- - lib/netdev.c | 28 +- - lib/netflow.h | 2 +- - lib/netlink-conntrack.c | 10 +- - lib/netlink-conntrack.h | 8 +- - lib/netlink-notifier.c | 4 +- - lib/netlink-socket.c | 16 +- - lib/netlink-socket.h | 4 +- - lib/netlink.c | 14 +- - lib/nx-match.c | 14 +- - lib/object-collection.c | 2 +- - lib/odp-execute.c | 16 +- - lib/odp-util.c | 24 +- - lib/odp-util.h | 6 +- - lib/ofp-actions.c | 12 +- - lib/ofp-bundle.c | 2 +- - lib/ofp-connection.c | 4 +- - lib/ofp-ed-props.c | 4 +- - lib/ofp-errors.c | 4 +- - lib/ofp-flow.c | 10 +- - lib/ofp-group.c | 8 +- - lib/ofp-ipfix.c | 4 +- - lib/ofp-match.c | 6 +- - lib/ofp-meter.c | 4 +- - lib/ofp-monitor.c | 6 +- - lib/ofp-msgs.c | 8 +- - lib/ofp-packet.c | 8 +- - lib/ofp-parse.c | 8 +- - lib/ofp-port.c | 4 +- - lib/ofp-print.c | 22 +- - lib/ofp-prop.c | 6 +- - lib/ofp-protocol.c | 2 +- - lib/ofp-queue.c | 6 +- - lib/ofp-switch.c | 4 +- - lib/ofp-table.c | 6 +- - lib/ofp-util.c | 26 +- - lib/ofp-version-opt.c | 2 +- - lib/ofp-version-opt.h | 2 +- - lib/ofpbuf.c | 2 +- - lib/ovs-lldp.c | 12 +- - lib/ovs-lldp.h | 8 +- - lib/ovs-numa.c | 8 +- - lib/ovs-rcu.c | 14 +- - lib/ovs-replay.c | 6 +- - lib/ovs-router.c | 20 +- - lib/ovs-router.h | 2 +- - lib/ovs-thread.c | 14 +- - lib/ovsdb-condition.c | 4 +- - lib/ovsdb-cs.c | 22 +- - lib/ovsdb-data.c | 16 +- - lib/ovsdb-error.c | 4 +- - lib/ovsdb-idl.c | 34 +- - lib/ovsdb-map-op.c | 6 +- - lib/ovsdb-parser.c | 4 +- - lib/ovsdb-session.c | 6 +- - lib/ovsdb-set-op.c | 4 +- - lib/ovsdb-types.c | 12 +- - lib/ox-stat.c | 4 +- - lib/packets.c | 16 +- - lib/pcap-file.c | 14 +- - lib/perf-counter.c | 2 +- - lib/poll-loop.c | 14 +- - lib/process.c | 14 +- - lib/pvector.c | 2 +- - lib/random.c | 10 +- - lib/rconn.c | 10 +- - lib/reconnect.c | 2 +- - lib/route-table-bsd.c | 4 +- - lib/route-table.c | 8 +- - lib/rstp-common.h | 4 +- - lib/rstp-state-machines.c | 12 +- - lib/rstp.c | 12 +- - lib/rstp.h | 2 +- - lib/rtbsd.c | 4 +- - lib/rtnetlink.c | 4 +- - lib/seq.c | 10 +- - lib/sflow_agent.c | 2 +- - lib/sha1.c | 2 +- - lib/shash.c | 2 +- - lib/signals.c | 4 +- - lib/simap.c | 4 +- - lib/skiplist.c | 6 +- - lib/smap.c | 10 +- - lib/socket-util-unix.c | 8 +- - lib/socket-util.c | 10 +- - lib/sort.c | 4 +- - lib/sset.c | 4 +- - lib/stopwatch.c | 12 +- - lib/stp.c | 14 +- - lib/stp.h | 2 +- - lib/stream-fd.c | 8 +- - lib/stream-nossl.c | 2 +- - lib/stream-provider.h | 2 +- - lib/stream-replay.c | 6 +- - lib/stream-ssl.c | 16 +- - lib/stream-tcp.c | 8 +- - lib/stream-unix.c | 12 +- - lib/stream-windows.c | 6 +- - lib/stream.c | 18 +- - lib/string.c | 2 +- - lib/strsep.c | 2 +- - lib/svec.c | 6 +- - lib/syslog-direct.c | 4 +- - lib/syslog-libc.c | 4 +- - lib/syslog-null.c | 2 +- - lib/table.c | 10 +- - lib/tc.c | 10 +- - lib/timer.c | 4 +- - lib/timeval.c | 18 +- - lib/tnl-neigh-cache.c | 28 +- - lib/tnl-neigh-cache.h | 8 +- - lib/tnl-ports.c | 12 +- - lib/tnl-ports.h | 6 +- - lib/token-bucket.c | 4 +- - lib/tun-metadata.c | 12 +- - lib/unicode.c | 2 +- - lib/unixctl.c | 12 +- - lib/userspace-tso.c | 4 +- - lib/util.c | 16 +- - lib/util.h | 1 - - lib/uuid.c | 10 +- - lib/vconn-provider.h | 2 +- - lib/vconn-stream.c | 8 +- - lib/vconn.c | 14 +- - lib/vl-mff-map.h | 2 +- - lib/vlan-bitmap.h | 2 +- - lib/vlog.c | 16 +- - lib/wmi.c | 2 +- - ofproto/bond.c | 18 +- - ofproto/bond.h | 2 +- - ofproto/bundles.c | 8 +- - ofproto/bundles.h | 2 +- - ofproto/collectors.c | 6 +- - ofproto/connmgr.c | 12 +- - ofproto/connmgr.h | 2 +- - ofproto/fail-open.c | 8 +- - ofproto/in-band.c | 14 +- - ofproto/in-band.h | 2 +- - ofproto/netflow.c | 12 +- - ofproto/netflow.h | 4 +- - ofproto/ofproto-dpif-ipfix.c | 18 +- - ofproto/ofproto-dpif-mirror.c | 4 +- - ofproto/ofproto-dpif-mirror.h | 2 +- - ofproto/ofproto-dpif-monitor.c | 14 +- - ofproto/ofproto-dpif-monitor.h | 2 +- - ofproto/ofproto-dpif-rid.h | 6 +- - ofproto/ofproto-dpif-sflow.c | 14 +- - ofproto/ofproto-dpif-sflow.h | 2 +- - ofproto/ofproto-dpif-trace.c | 2 +- - ofproto/ofproto-dpif-trace.h | 2 +- - ofproto/ofproto-dpif-upcall.c | 16 +- - ofproto/ofproto-dpif-xlate-cache.c | 14 +- - ofproto/ofproto-dpif-xlate-cache.h | 2 +- - ofproto/ofproto-dpif-xlate.c | 24 +- - ofproto/ofproto-dpif-xlate.h | 6 +- - ofproto/ofproto-dpif.c | 34 +- - ofproto/ofproto-dpif.h | 8 +- - ofproto/ofproto-provider.h | 18 +- - ofproto/ofproto.c | 40 +- - ofproto/ofproto.h | 8 +- - ofproto/pinsched.c | 8 +- - ofproto/pinsched.h | 2 +- - ofproto/tunnel.c | 20 +- - ofproto/tunnel.h | 2 +- - ovsdb/column.c | 6 +- - ovsdb/column.h | 2 +- - ovsdb/condition.c | 4 +- - ovsdb/condition.h | 6 +- - ovsdb/execution.c | 8 +- - ovsdb/file.c | 14 +- - ovsdb/jsonrpc-server.c | 16 +- - ovsdb/log.c | 14 +- - ovsdb/monitor.c | 16 +- - ovsdb/mutation.c | 4 +- - ovsdb/mutation.h | 2 +- - ovsdb/ovsdb-client.c | 30 +- - ovsdb/ovsdb-idlc.in | 16 +- - ovsdb/ovsdb-server.c | 36 +- - ovsdb/ovsdb-tool.c | 21 +- - ovsdb/ovsdb-util.c | 2 +- - ovsdb/ovsdb.c | 10 +- - ovsdb/raft-private.c | 10 +- - ovsdb/raft-private.h | 2 +- - ovsdb/raft-rpc.c | 8 +- - ovsdb/raft-rpc.h | 2 +- - ovsdb/raft.c | 24 +- - ovsdb/raft.h | 2 +- - ovsdb/rbac.c | 8 +- - ovsdb/relay.c | 12 +- - ovsdb/replication.c | 12 +- - ovsdb/row.c | 6 +- - ovsdb/row.h | 2 +- - ovsdb/server.c | 4 +- - ovsdb/storage.c | 10 +- - ovsdb/table.c | 6 +- - ovsdb/transaction-forward.c | 8 +- - ovsdb/transaction.c | 8 +- - ovsdb/trigger.c | 6 +- - tests/oss-fuzz/flow_extract_target.c | 6 +- - tests/oss-fuzz/json_parser_target.c | 4 +- - tests/oss-fuzz/miniflow_target.c | 8 +- - tests/oss-fuzz/odp_target.c | 4 +- - tests/oss-fuzz/ofctl_parse_target.c | 2 +- - tests/oss-fuzz/ofp_print_target.c | 2 +- - tests/ovstest.c | 4 +- - tests/ovstest.h | 2 +- - tests/test-aes128.c | 2 +- - tests/test-atomic.c | 10 +- - tests/test-barrier.c | 8 +- - tests/test-bitmap.c | 6 +- - tests/test-bundle.c | 6 +- - tests/test-byte-order.c | 2 +- - tests/test-ccmap.c | 14 +- - tests/test-classifier.c | 24 +- - tests/test-cmap.c | 16 +- - tests/test-conntrack.c | 12 +- - tests/test-csum.c | 12 +- - tests/test-flows.c | 10 +- - tests/test-hash.c | 2 +- - tests/test-heap.c | 6 +- - tests/test-hindex.c | 8 +- - tests/test-hmap.c | 6 +- - tests/test-id-fpool.c | 16 +- - tests/test-json.c | 6 +- - tests/test-jsonrpc.c | 14 +- - tests/test-lockfile.c | 6 +- - tests/test-mpsc-queue.c | 10 +- - tests/test-multipath.c | 4 +- - tests/test-netflow.c | 12 +- - tests/test-netlink-policy.c | 4 +- - tests/test-odp.c | 4 +- - tests/test-ofpbuf.c | 2 +- - tests/test-ovsdb.c | 22 +- - tests/test-packets.c | 2 +- - tests/test-random.c | 2 +- - tests/test-rcu.c | 8 +- - tests/test-reconnect.c | 6 +- - tests/test-rstp.c | 4 +- - tests/test-sflow.c | 12 +- - tests/test-sha1.c | 4 +- - tests/test-skiplist.c | 6 +- - tests/test-stopwatch.c | 4 +- - tests/test-stp.c | 4 +- - tests/test-stream.c | 6 +- - tests/test-unix-socket.c | 4 +- - tests/test-unixctl.c | 10 +- - tests/test-util.c | 8 +- - tests/test-uuid.c | 4 +- - tests/test-vconn.c | 14 +- - utilities/nlmon.c | 6 +- - utilities/ovs-appctl.c | 16 +- - utilities/ovs-dpctl.c | 12 +- - utilities/ovs-ofctl.c | 34 +- - utilities/ovs-testcontroller.c | 18 +- - utilities/ovs-vsctl.c | 34 +- - vswitchd/bridge.c | 42 +- - vswitchd/ovs-vswitchd.c | 32 +- - vswitchd/system-stats.c | 16 +- - vswitchd/xenserver.c | 4 +- - vtep/vtep-ctl.c | 30 +- - 488 files changed, 2592 insertions(+), 1822 deletions(-) - create mode 100644 include/internal/automake.mk - rename {lib => include/internal}/bitmap.h (99%) - rename {lib => include/internal}/bundle.h (100%) - rename {lib => include/internal}/byte-order.h (100%) - rename {lib => include/internal}/classifier.h (99%) - rename {lib => include/internal}/cmap.h (99%) - rename {lib => include/internal}/colors.h (100%) - rename {lib => include/internal}/command-line.h (100%) - rename {lib => include/internal}/coverage.h (99%) - rename {lib => include/internal}/crc32c.h (100%) - rename {lib => include/internal}/csum.h (100%) - rename {lib => include/internal}/daemon.h (100%) - rename {lib => include/internal}/db-ctl-base.h (100%) - rename {lib => include/internal}/dhcp.h (97%) - rename {lib => include/internal}/dhparams.h (100%) - rename {lib => include/internal}/dirs.h (100%) - rename {lib => include/internal}/dp-packet.h (99%) - rename {lib => include/internal}/fatal-signal.h (100%) - rename {lib => include/internal}/flow.h (99%) - rename {lib => include/internal}/hash-aarch64.h (100%) - rename {lib => include/internal}/hash.h (99%) - rename {lib => include/internal}/hindex.h (99%) - rename {lib => include/internal}/hmapx.h (100%) - rename {lib => include/internal}/id-pool.h (100%) - rename {lib => include/internal}/jsonrpc.h (100%) - rename {lib => include/internal}/latch.h (97%) - rename {lib => include/internal}/mcast-snooping.h (97%) - rename {lib => include/internal}/memory.h (100%) - rename {lib => include/internal}/netdev-afxdp.h (100%) - rename {lib => include/internal}/netdev-dpdk.h (100%) - rename {lib => include/internal}/netdev.h (99%) - rename {lib => include/internal}/netlink-protocol.h (99%) - rename {lib => include/internal}/netlink.h (99%) - rename {lib => include/internal}/nx-match.h (99%) - rename {lib => include/internal}/ovs-atomic-c++.h (100%) - rename {lib => include/internal}/ovs-atomic-c11.h (100%) - rename {lib => include/internal}/ovs-atomic-clang.h (98%) - rename {lib => include/internal}/ovs-atomic-flag-gcc4.7+.h (100%) - rename {lib => include/internal}/ovs-atomic-gcc4+.h (99%) - rename {lib => include/internal}/ovs-atomic-gcc4.7+.h (98%) - rename {lib => include/internal}/ovs-atomic-i586.h (100%) - rename {lib => include/internal}/ovs-atomic-locked.c (94%) - rename {lib => include/internal}/ovs-atomic-locked.h (100%) - rename {lib => include/internal}/ovs-atomic-msvc.h (100%) - rename {lib => include/internal}/ovs-atomic-pthreads.h (99%) - rename {lib => include/internal}/ovs-atomic-x86_64.h (100%) - rename {lib => include/internal}/packets.h (99%) - rename {lib => include/internal}/process.h (100%) - rename {lib => include/internal}/pvector.h (99%) - rename {lib => include/internal}/random.h (100%) - rename {lib => include/internal}/rculist.h (99%) - rename {lib => include/internal}/seq.h (99%) - rename {lib => include/internal}/simap.h (100%) - rename {lib => include/internal}/skiplist.h (100%) - rename {lib => include/internal}/smap.h (99%) - rename {lib => include/internal}/socket-util.h (100%) - rename {lib => include/internal}/sort.h (100%) - rename {lib => include/internal}/sset.h (99%) - rename {lib => include/internal}/stopwatch.h (100%) - rename {lib => include/internal}/stream-ssl.h (100%) - rename {lib => include/internal}/stream.h (98%) - rename {lib => include/internal}/svec.h (100%) - rename {lib => include/internal}/table.h (100%) - rename {lib => include/internal}/timer.h (96%) - rename {lib => include/internal}/timeval.h (98%) - rename lib/tun-metadata.h => include/internal/tun-metadata-private.h (99%) - rename {lib => include/internal}/unaligned.h (99%) - rename {lib => include/internal}/unixctl.h (100%) - create mode 100644 include/internal/util.h - rename {lib => include/internal}/uuid.h (100%) - rename {lib => include/internal}/versions.h (98%) - rename {lib => include/openvswitch}/ovs-atomic.h (97%) - rename {lib => include/openvswitch}/ovs-numa.h (96%) - rename {lib => include/openvswitch}/ovs-rcu.h (99%) - rename {lib => include/openvswitch}/ovs-thread.h (99%) - rename {lib => include/openvswitch}/ovsdb-condition.h (95%) - rename {lib => include/openvswitch}/ovsdb-cs.h (98%) - rename {lib => include/openvswitch}/ovsdb-data.h (99%) - rename {lib => include/openvswitch}/ovsdb-error.h (97%) - rename {lib => include/openvswitch}/ovsdb-idl-provider.h (97%) - rename {lib => include/openvswitch}/ovsdb-idl.h (99%) - rename {lib => include/openvswitch}/ovsdb-map-op.h (97%) - rename {lib => include/openvswitch}/ovsdb-parser.h (96%) - rename {lib => include/openvswitch}/ovsdb-set-op.h (97%) - rename {lib => include/openvswitch}/ovsdb-types.h (99%) - -Index: openvswitch-2.17.2/Makefile.am -=================================================================== ---- openvswitch-2.17.2.orig/Makefile.am -+++ openvswitch-2.17.2/Makefile.am -@@ -242,7 +242,7 @@ config-h-check: - exit 1; \ - fi; \ - if grep '#include' include/openvswitch/*.h | \ -- grep -vE '(<.*>)|("openvswitch)|("openflow)'; \ -+ grep -vE '(<.*>)|("openvswitch)|("openflow)|("internal)'; \ - then \ - echo "See above for list of violations of the rule that"; \ - echo "public openvswitch header file should not include internal library."; \ -Index: openvswitch-2.17.2/build-aux/extract-odp-netlink-h -=================================================================== ---- openvswitch-2.17.2.orig/build-aux/extract-odp-netlink-h -+++ openvswitch-2.17.2/build-aux/extract-odp-netlink-h -@@ -8,6 +8,9 @@ - /* -*- mode: c; buffer-read-only: t -*- */\ - /* Generated automatically from -- do not modify! */\ - \ -+#ifdef __cplusplus\ -+extern "C" {\ -+#endif\ - \ - - -@@ -65,3 +68,9 @@ s/__be16/ovs_be16/g - # boundary. - s/__u64/ovs_32aligned_u64/g - s/__be64/ovs_32aligned_be64/g -+ -+$a\ -+#ifdef __cplusplus\ -+} // extern "C"\ -+#endif\ -+\ -Index: openvswitch-2.17.2/build-aux/extract-odp-netlink-macros-h -=================================================================== ---- openvswitch-2.17.2.orig/build-aux/extract-odp-netlink-macros-h -+++ openvswitch-2.17.2/build-aux/extract-odp-netlink-macros-h -@@ -42,6 +42,9 @@ echo "/* Generated automatically from --#include "flow.h" -+#include "internal/flow.h" - - struct ovs_conntrack_info; - struct ovs_ct_limit_info; -Index: openvswitch-2.17.2/datapath/datapath.c -=================================================================== ---- openvswitch-2.17.2.orig/datapath/datapath.c -+++ openvswitch-2.17.2/datapath/datapath.c -@@ -55,7 +55,7 @@ - - #include "datapath.h" - #include "conntrack.h" --#include "flow.h" -+#include "internal/flow.h" - #include "flow_table.h" - #include "flow_netlink.h" - #include "meter.h" -Index: openvswitch-2.17.2/datapath/datapath.h -=================================================================== ---- openvswitch-2.17.2.orig/datapath/datapath.h -+++ openvswitch-2.17.2/datapath/datapath.h -@@ -29,7 +29,7 @@ - #include - - #include "compat.h" --#include "flow.h" -+#include "internal/flow.h" - #include "flow_table.h" - #include "meter.h" - #include "vport-internal_dev.h" -Index: openvswitch-2.17.2/datapath/flow.c -=================================================================== ---- openvswitch-2.17.2.orig/datapath/flow.c -+++ openvswitch-2.17.2/datapath/flow.c -@@ -50,7 +50,7 @@ - - #include "datapath.h" - #include "conntrack.h" --#include "flow.h" -+#include "internal/flow.h" - #include "flow_netlink.h" - #include "vport.h" - -Index: openvswitch-2.17.2/datapath/flow_netlink.c -=================================================================== ---- openvswitch-2.17.2.orig/datapath/flow_netlink.c -+++ openvswitch-2.17.2/datapath/flow_netlink.c -@@ -51,7 +51,7 @@ - - #include "datapath.h" - #include "conntrack.h" --#include "flow.h" -+#include "internal/flow.h" - #include "flow_netlink.h" - #include "gso.h" - -Index: openvswitch-2.17.2/datapath/flow_netlink.h -=================================================================== ---- openvswitch-2.17.2.orig/datapath/flow_netlink.h -+++ openvswitch-2.17.2/datapath/flow_netlink.h -@@ -34,7 +34,7 @@ - #include - #include - --#include "flow.h" -+#include "internal/flow.h" - - size_t ovs_tun_key_attr_size(void); - size_t ovs_key_attr_size(void); -Index: openvswitch-2.17.2/datapath/flow_table.c -=================================================================== ---- openvswitch-2.17.2.orig/datapath/flow_table.c -+++ openvswitch-2.17.2/datapath/flow_table.c -@@ -16,7 +16,7 @@ - * 02110-1301, USA - */ - --#include "flow.h" -+#include "internal/flow.h" - #include "datapath.h" - #include - #include -Index: openvswitch-2.17.2/datapath/flow_table.h -=================================================================== ---- openvswitch-2.17.2.orig/datapath/flow_table.h -+++ openvswitch-2.17.2/datapath/flow_table.h -@@ -33,7 +33,7 @@ - #include - #include - --#include "flow.h" -+#include "internal/flow.h" - - struct mask_cache_entry { - u32 skb_hash; -Index: openvswitch-2.17.2/datapath/meter.h -=================================================================== ---- openvswitch-2.17.2.orig/datapath/meter.h -+++ openvswitch-2.17.2/datapath/meter.h -@@ -17,7 +17,7 @@ - #include - #include - --#include "flow.h" -+#include "internal/flow.h" - struct datapath; - - #define DP_MAX_BANDS 1 -Index: openvswitch-2.17.2/include/automake.mk -=================================================================== ---- openvswitch-2.17.2.orig/include/automake.mk -+++ openvswitch-2.17.2/include/automake.mk -@@ -16,3 +16,4 @@ include include/openvswitch/automake.mk - include include/sparse/automake.mk - include include/windows/automake.mk - include include/linux/automake.mk -+include include/internal/automake.mk -Index: openvswitch-2.17.2/include/internal/automake.mk -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/automake.mk -@@ -0,0 +1,77 @@ -+# Common headers needed by openvswitch and some depending projects like OVN -+ -+ovslibincludedir = $(openvswitchincludedir)/internal -+ovslibinclude_HEADERS = \ -+ include/internal/bitmap.h \ -+ include/internal/byte-order.h \ -+ include/internal/classifier.h \ -+ include/internal/cmap.h \ -+ include/internal/colors.h \ -+ include/internal/command-line.h \ -+ include/internal/coverage.h \ -+ include/internal/csum.h \ -+ include/internal/daemon.h \ -+ include/internal/db-ctl-base.h \ -+ include/internal/dirs.h \ -+ include/internal/dp-packet.h \ -+ include/internal/fatal-signal.h \ -+ include/internal/flow.h \ -+ include/internal/hash.h \ -+ include/internal/hash-aarch64.h \ -+ include/internal/hindex.h \ -+ include/internal/hmapx.h \ -+ include/internal/jsonrpc.h \ -+ include/internal/latch.h \ -+ include/internal/mcast-snooping.h \ -+ include/internal/memory.h \ -+ include/internal/netdev-afxdp.h \ -+ include/internal/netdev-dpdk.h \ -+ include/internal/netlink.h \ -+ include/internal/bundle.h \ -+ include/internal/crc32c.h \ -+ include/internal/dhcp.h \ -+ include/internal/dhparams.h \ -+ include/internal/id-pool.h \ -+ include/internal/netdev.h \ -+ include/internal/netlink-protocol.h \ -+ include/internal/nx-match.h \ -+ include/internal/ovs-atomic-c11.h \ -+ include/internal/ovs-atomic-c++.h \ -+ include/internal/ovs-atomic-clang.h \ -+ include/internal/ovs-atomic-flag-gcc4.7+.h \ -+ include/internal/ovs-atomic-gcc4.7+.h \ -+ include/internal/ovs-atomic-gcc4+.h \ -+ include/internal/ovs-atomic-i586.h \ -+ include/internal/ovs-atomic-locked.c \ -+ include/internal/ovs-atomic-locked.h \ -+ include/internal/ovs-atomic-msvc.h \ -+ include/internal/ovs-atomic-pthreads.h \ -+ include/internal/ovs-atomic-x86_64.h \ -+ include/internal/packets.h \ -+ include/internal/process.h \ -+ include/internal/pvector.h \ -+ include/internal/random.h \ -+ include/internal/rculist.h \ -+ include/internal/seq.h \ -+ include/internal/simap.h \ -+ include/internal/skiplist.h \ -+ include/internal/smap.h \ -+ include/internal/socket-util.h \ -+ include/internal/sort.h \ -+ include/internal/sset.h \ -+ include/internal/stopwatch.h \ -+ include/internal/stream.h \ -+ include/internal/stream-ssl.h \ -+ include/internal/svec.h \ -+ include/internal/table.h \ -+ include/internal/timer.h \ -+ include/internal/timeval.h \ -+ include/internal/tun-metadata-private.h \ -+ include/internal/unaligned.h \ -+ include/internal/unixctl.h \ -+ include/internal/util.h \ -+ include/internal/uuid.h \ -+ include/internal/versions.h \ -+ lib/vswitch-idl.h \ -+ vtep/vtep-idl.h -+ -Index: openvswitch-2.17.2/lib/bitmap.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/bitmap.h -+++ /dev/null -@@ -1,295 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef BITMAP_H --#define BITMAP_H 1 -- --#include --#include --#include "util.h" -- --static inline unsigned long * --bitmap_unit__(const unsigned long *bitmap, size_t offset) --{ -- return CONST_CAST(unsigned long *, &bitmap[offset / BITMAP_ULONG_BITS]); --} -- --static inline unsigned long --bitmap_bit__(size_t offset) --{ -- return 1UL << (offset % BITMAP_ULONG_BITS); --} -- --static inline size_t --bitmap_n_longs(size_t n_bits) --{ -- return BITMAP_N_LONGS(n_bits); --} -- --static inline size_t --bitmap_n_bytes(size_t n_bits) --{ -- return bitmap_n_longs(n_bits) * sizeof(unsigned long int); --} -- --static inline unsigned long * --bitmap_allocate(size_t n_bits) --{ -- return xzalloc(bitmap_n_bytes(n_bits)); --} -- --/* Initializes bitmap to all-1-bits and returns the bitmap pointer. */ --static inline unsigned long * --bitmap_init1(unsigned long *bitmap, size_t n_bits) --{ -- size_t n_longs = bitmap_n_longs(n_bits); -- size_t n_bytes = bitmap_n_bytes(n_bits); -- size_t r_bits = n_bits % BITMAP_ULONG_BITS; -- -- memset(bitmap, 0xff, n_bytes); -- if (r_bits) { -- bitmap[n_longs - 1] = (1UL << r_bits) - 1; -- } -- return bitmap; --} -- --/* Allocates and returns a bitmap initialized to all-1-bits. */ --static inline unsigned long * --bitmap_allocate1(size_t n_bits) --{ -- return bitmap_init1(xmalloc(bitmap_n_bytes(n_bits)), n_bits); --} -- --static inline unsigned long * --bitmap_clone(const unsigned long *bitmap, size_t n_bits) --{ -- return xmemdup(bitmap, bitmap_n_bytes(n_bits)); --} -- --static inline void --bitmap_free(unsigned long *bitmap) --{ -- free(bitmap); --} -- --static inline bool --bitmap_is_set(const unsigned long *bitmap, size_t offset) --{ -- return (*bitmap_unit__(bitmap, offset) & bitmap_bit__(offset)) != 0; --} -- --static inline unsigned long * --bitmap_set1(unsigned long *bitmap, size_t offset) --{ -- *bitmap_unit__(bitmap, offset) |= bitmap_bit__(offset); -- return bitmap; --} -- --static inline unsigned long * --bitmap_set0(unsigned long *bitmap, size_t offset) --{ -- *bitmap_unit__(bitmap, offset) &= ~bitmap_bit__(offset); -- return bitmap; --} -- --static inline unsigned long * --bitmap_set(unsigned long *bitmap, size_t offset, bool value) --{ -- return (value) ? bitmap_set1(bitmap, offset) : bitmap_set0(bitmap, offset); --} -- --/* Sets 'n' bits of a single unit. */ --static inline void --bitmap_set_n__(unsigned long *bitmap, size_t start, size_t n, bool value) --{ -- unsigned long mask = ((1UL << n) - 1) << start % BITMAP_ULONG_BITS; -- -- if (value) { -- *bitmap_unit__(bitmap, start) |= mask; -- } else { -- *bitmap_unit__(bitmap, start) &= ~mask; -- } --} -- --/* Sets 'count' consecutive bits in 'bitmap', starting at bit offset 'start', -- * to 'value'. */ --static inline unsigned long * --bitmap_set_multiple(unsigned long *bitmap, size_t start, size_t count, -- bool value) --{ -- if (count && start % BITMAP_ULONG_BITS) { -- size_t n = MIN(count, BITMAP_ULONG_BITS - start % BITMAP_ULONG_BITS); -- -- bitmap_set_n__(bitmap, start, n, value); -- count -= n; -- start += n; -- } -- for (; count >= BITMAP_ULONG_BITS; count -= BITMAP_ULONG_BITS) { -- *bitmap_unit__(bitmap, start) = (unsigned long)!value - 1; -- start += BITMAP_ULONG_BITS; -- } -- if (count) { -- bitmap_set_n__(bitmap, start, count, value); -- } -- return bitmap; --} -- --/* Returns the number of 1-bits in the 'n'-bit bitmap at 'bitmap'. */ --static inline size_t --bitmap_count1(const unsigned long int *bitmap, size_t n) --{ -- size_t i; -- size_t count = 0; -- -- BUILD_ASSERT(ULONG_MAX <= UINT64_MAX); -- for (i = 0; i < BITMAP_N_LONGS(n); i++) { -- count += count_1bits(bitmap[i]); -- } -- return count; --} -- --/* "dst &= arg;" for n-bit dst and arg. */ --static inline unsigned long * --bitmap_and(unsigned long *dst, const unsigned long *arg, size_t n) --{ -- size_t i; -- -- for (i = 0; i < BITMAP_N_LONGS(n); i++) { -- dst[i] &= arg[i]; -- } -- return dst; --} -- --/* "dst |= arg;" for n-bit dst and arg. */ --static inline unsigned long * --bitmap_or(unsigned long *dst, const unsigned long *arg, size_t n) --{ -- size_t i; -- -- for (i = 0; i < BITMAP_N_LONGS(n); i++) { -- dst[i] |= arg[i]; -- } -- return dst; --} -- --/* "dst = ~dst;" for n-bit dst. */ --static inline unsigned long * --bitmap_not(unsigned long *dst, size_t n) --{ -- size_t i; -- -- for (i = 0; i < n / BITMAP_ULONG_BITS; i++) { -- dst[i] = ~dst[i]; -- } -- if (n % BITMAP_ULONG_BITS) { -- dst[i] ^= (1UL << (n % BITMAP_ULONG_BITS)) - 1; -- } -- return dst; --} -- --/* Compares the 'n' bits in bitmaps 'a' and 'b'. Returns true if all bits are -- * equal, false otherwise. */ --static inline bool --bitmap_equal(const unsigned long *a, const unsigned long *b, size_t n) --{ -- if (memcmp(a, b, n / BITMAP_ULONG_BITS * sizeof(unsigned long))) { -- return false; -- } -- if (n % BITMAP_ULONG_BITS) { -- unsigned long mask = (1UL << n % BITMAP_ULONG_BITS) - 1; -- unsigned long diff = *bitmap_unit__(a, n) ^ *bitmap_unit__(b, n); -- -- return !(diff & mask); -- } -- return true; --} -- --/* Scans 'bitmap' from bit offset 'start' to 'end', excluding 'end' itself. -- * Returns the bit offset of the lowest-numbered bit set to 'target', or 'end' -- * if all of the bits are set to '!target'. 'target' is typically a -- * compile-time constant, so it makes sense to inline this. Compiler may also -- * optimize parts away depending on the 'start' and 'end' values passed in. */ --static inline size_t --bitmap_scan(const unsigned long *bitmap, bool target, size_t start, size_t end) --{ -- if (OVS_LIKELY(start < end)) { -- unsigned long *p, unit; -- -- p = bitmap_unit__(bitmap, start); -- unit = (target ? *p : ~*p) >> (start % BITMAP_ULONG_BITS); -- if (!unit) { -- start -= start % BITMAP_ULONG_BITS; /* Round down. */ -- start += BITMAP_ULONG_BITS; /* Start of the next unit. */ -- -- for (; start < end; start += BITMAP_ULONG_BITS) { -- unit = target ? *++p : ~*++p; -- if (unit) { -- goto found; -- } -- } -- return end; -- } --found: -- start += raw_ctz(unit); /* unit != 0 */ -- if (OVS_LIKELY(start < end)) { -- return start; -- } -- } -- return end; --} -- --/* Returns true if the 1-bits in 'super' are a superset of the 1-bits in 'sub', -- * false otherwise. 'super' and 'sub' both have 'n_bits' bits. */ --static inline bool --bitmap_is_superset(const unsigned long int *super, -- const unsigned long int *sub, size_t n_bits) --{ -- size_t n_longs = bitmap_n_longs(n_bits); -- for (size_t i = 0; i < n_longs; i++) { -- if (!uint_is_superset(super[i], sub[i])) { -- return false; -- } -- } -- return true; --} -- --/* Returns true if all of the 'n' bits in 'bitmap' are 0, -- * false if at least one bit is a 1.*/ --static inline bool --bitmap_is_all_zeros(const unsigned long *bitmap, size_t n) --{ -- return bitmap_scan(bitmap, true, 0, n) == n; --} -- --#define BITMAP_FOR_EACH_1_RANGE(IDX, BEGIN, END, BITMAP) \ -- for ((IDX) = bitmap_scan(BITMAP, true, BEGIN, END); (IDX) < (END); \ -- (IDX) = bitmap_scan(BITMAP, true, (IDX) + 1, END)) --#define BITMAP_FOR_EACH_1(IDX, SIZE, BITMAP) \ -- BITMAP_FOR_EACH_1_RANGE(IDX, 0, SIZE, BITMAP) -- --/* More efficient access to a map of single ullong. */ --#define ULLONG_FOR_EACH_1(IDX, MAP) \ -- for (uint64_t map__ = (MAP); \ -- map__ && (((IDX) = raw_ctz(map__)), true); \ -- map__ = zero_rightmost_1bit(map__)) -- --#define ULLONG_SET0(MAP, OFFSET) ((MAP) &= ~(1ULL << (OFFSET))) --#define ULLONG_SET1(MAP, OFFSET) ((MAP) |= 1ULL << (OFFSET)) -- --/* Returns the value of a bit in a map as a bool. */ --#define ULLONG_GET(MAP, OFFSET) !!((MAP) & (1ULL << (OFFSET))) -- --#endif /* bitmap.h */ -Index: openvswitch-2.17.2/include/internal/bitmap.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/bitmap.h -@@ -0,0 +1,295 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef BITMAP_H -+#define BITMAP_H 1 -+ -+#include -+#include -+#include "internal/util.h" -+ -+static inline unsigned long * -+bitmap_unit__(const unsigned long *bitmap, size_t offset) -+{ -+ return CONST_CAST(unsigned long *, &bitmap[offset / BITMAP_ULONG_BITS]); -+} -+ -+static inline unsigned long -+bitmap_bit__(size_t offset) -+{ -+ return 1UL << (offset % BITMAP_ULONG_BITS); -+} -+ -+static inline size_t -+bitmap_n_longs(size_t n_bits) -+{ -+ return BITMAP_N_LONGS(n_bits); -+} -+ -+static inline size_t -+bitmap_n_bytes(size_t n_bits) -+{ -+ return bitmap_n_longs(n_bits) * sizeof(unsigned long int); -+} -+ -+static inline unsigned long * -+bitmap_allocate(size_t n_bits) -+{ -+ return xzalloc(bitmap_n_bytes(n_bits)); -+} -+ -+/* Initializes bitmap to all-1-bits and returns the bitmap pointer. */ -+static inline unsigned long * -+bitmap_init1(unsigned long *bitmap, size_t n_bits) -+{ -+ size_t n_longs = bitmap_n_longs(n_bits); -+ size_t n_bytes = bitmap_n_bytes(n_bits); -+ size_t r_bits = n_bits % BITMAP_ULONG_BITS; -+ -+ memset(bitmap, 0xff, n_bytes); -+ if (r_bits) { -+ bitmap[n_longs - 1] = (1UL << r_bits) - 1; -+ } -+ return bitmap; -+} -+ -+/* Allocates and returns a bitmap initialized to all-1-bits. */ -+static inline unsigned long * -+bitmap_allocate1(size_t n_bits) -+{ -+ return bitmap_init1(xmalloc(bitmap_n_bytes(n_bits)), n_bits); -+} -+ -+static inline unsigned long * -+bitmap_clone(const unsigned long *bitmap, size_t n_bits) -+{ -+ return xmemdup(bitmap, bitmap_n_bytes(n_bits)); -+} -+ -+static inline void -+bitmap_free(unsigned long *bitmap) -+{ -+ free(bitmap); -+} -+ -+static inline bool -+bitmap_is_set(const unsigned long *bitmap, size_t offset) -+{ -+ return (*bitmap_unit__(bitmap, offset) & bitmap_bit__(offset)) != 0; -+} -+ -+static inline unsigned long * -+bitmap_set1(unsigned long *bitmap, size_t offset) -+{ -+ *bitmap_unit__(bitmap, offset) |= bitmap_bit__(offset); -+ return bitmap; -+} -+ -+static inline unsigned long * -+bitmap_set0(unsigned long *bitmap, size_t offset) -+{ -+ *bitmap_unit__(bitmap, offset) &= ~bitmap_bit__(offset); -+ return bitmap; -+} -+ -+static inline unsigned long * -+bitmap_set(unsigned long *bitmap, size_t offset, bool value) -+{ -+ return (value) ? bitmap_set1(bitmap, offset) : bitmap_set0(bitmap, offset); -+} -+ -+/* Sets 'n' bits of a single unit. */ -+static inline void -+bitmap_set_n__(unsigned long *bitmap, size_t start, size_t n, bool value) -+{ -+ unsigned long mask = ((1UL << n) - 1) << start % BITMAP_ULONG_BITS; -+ -+ if (value) { -+ *bitmap_unit__(bitmap, start) |= mask; -+ } else { -+ *bitmap_unit__(bitmap, start) &= ~mask; -+ } -+} -+ -+/* Sets 'count' consecutive bits in 'bitmap', starting at bit offset 'start', -+ * to 'value'. */ -+static inline unsigned long * -+bitmap_set_multiple(unsigned long *bitmap, size_t start, size_t count, -+ bool value) -+{ -+ if (count && start % BITMAP_ULONG_BITS) { -+ size_t n = MIN(count, BITMAP_ULONG_BITS - start % BITMAP_ULONG_BITS); -+ -+ bitmap_set_n__(bitmap, start, n, value); -+ count -= n; -+ start += n; -+ } -+ for (; count >= BITMAP_ULONG_BITS; count -= BITMAP_ULONG_BITS) { -+ *bitmap_unit__(bitmap, start) = (unsigned long)!value - 1; -+ start += BITMAP_ULONG_BITS; -+ } -+ if (count) { -+ bitmap_set_n__(bitmap, start, count, value); -+ } -+ return bitmap; -+} -+ -+/* Returns the number of 1-bits in the 'n'-bit bitmap at 'bitmap'. */ -+static inline size_t -+bitmap_count1(const unsigned long int *bitmap, size_t n) -+{ -+ size_t i; -+ size_t count = 0; -+ -+ BUILD_ASSERT(ULONG_MAX <= UINT64_MAX); -+ for (i = 0; i < BITMAP_N_LONGS(n); i++) { -+ count += count_1bits(bitmap[i]); -+ } -+ return count; -+} -+ -+/* "dst &= arg;" for n-bit dst and arg. */ -+static inline unsigned long * -+bitmap_and(unsigned long *dst, const unsigned long *arg, size_t n) -+{ -+ size_t i; -+ -+ for (i = 0; i < BITMAP_N_LONGS(n); i++) { -+ dst[i] &= arg[i]; -+ } -+ return dst; -+} -+ -+/* "dst |= arg;" for n-bit dst and arg. */ -+static inline unsigned long * -+bitmap_or(unsigned long *dst, const unsigned long *arg, size_t n) -+{ -+ size_t i; -+ -+ for (i = 0; i < BITMAP_N_LONGS(n); i++) { -+ dst[i] |= arg[i]; -+ } -+ return dst; -+} -+ -+/* "dst = ~dst;" for n-bit dst. */ -+static inline unsigned long * -+bitmap_not(unsigned long *dst, size_t n) -+{ -+ size_t i; -+ -+ for (i = 0; i < n / BITMAP_ULONG_BITS; i++) { -+ dst[i] = ~dst[i]; -+ } -+ if (n % BITMAP_ULONG_BITS) { -+ dst[i] ^= (1UL << (n % BITMAP_ULONG_BITS)) - 1; -+ } -+ return dst; -+} -+ -+/* Compares the 'n' bits in bitmaps 'a' and 'b'. Returns true if all bits are -+ * equal, false otherwise. */ -+static inline bool -+bitmap_equal(const unsigned long *a, const unsigned long *b, size_t n) -+{ -+ if (memcmp(a, b, n / BITMAP_ULONG_BITS * sizeof(unsigned long))) { -+ return false; -+ } -+ if (n % BITMAP_ULONG_BITS) { -+ unsigned long mask = (1UL << n % BITMAP_ULONG_BITS) - 1; -+ unsigned long diff = *bitmap_unit__(a, n) ^ *bitmap_unit__(b, n); -+ -+ return !(diff & mask); -+ } -+ return true; -+} -+ -+/* Scans 'bitmap' from bit offset 'start' to 'end', excluding 'end' itself. -+ * Returns the bit offset of the lowest-numbered bit set to 'target', or 'end' -+ * if all of the bits are set to '!target'. 'target' is typically a -+ * compile-time constant, so it makes sense to inline this. Compiler may also -+ * optimize parts away depending on the 'start' and 'end' values passed in. */ -+static inline size_t -+bitmap_scan(const unsigned long *bitmap, bool target, size_t start, size_t end) -+{ -+ if (OVS_LIKELY(start < end)) { -+ unsigned long *p, unit; -+ -+ p = bitmap_unit__(bitmap, start); -+ unit = (target ? *p : ~*p) >> (start % BITMAP_ULONG_BITS); -+ if (!unit) { -+ start -= start % BITMAP_ULONG_BITS; /* Round down. */ -+ start += BITMAP_ULONG_BITS; /* Start of the next unit. */ -+ -+ for (; start < end; start += BITMAP_ULONG_BITS) { -+ unit = target ? *++p : ~*++p; -+ if (unit) { -+ goto found; -+ } -+ } -+ return end; -+ } -+found: -+ start += raw_ctz(unit); /* unit != 0 */ -+ if (OVS_LIKELY(start < end)) { -+ return start; -+ } -+ } -+ return end; -+} -+ -+/* Returns true if the 1-bits in 'super' are a superset of the 1-bits in 'sub', -+ * false otherwise. 'super' and 'sub' both have 'n_bits' bits. */ -+static inline bool -+bitmap_is_superset(const unsigned long int *super, -+ const unsigned long int *sub, size_t n_bits) -+{ -+ size_t n_longs = bitmap_n_longs(n_bits); -+ for (size_t i = 0; i < n_longs; i++) { -+ if (!uint_is_superset(super[i], sub[i])) { -+ return false; -+ } -+ } -+ return true; -+} -+ -+/* Returns true if all of the 'n' bits in 'bitmap' are 0, -+ * false if at least one bit is a 1.*/ -+static inline bool -+bitmap_is_all_zeros(const unsigned long *bitmap, size_t n) -+{ -+ return bitmap_scan(bitmap, true, 0, n) == n; -+} -+ -+#define BITMAP_FOR_EACH_1_RANGE(IDX, BEGIN, END, BITMAP) \ -+ for ((IDX) = bitmap_scan(BITMAP, true, BEGIN, END); (IDX) < (END); \ -+ (IDX) = bitmap_scan(BITMAP, true, (IDX) + 1, END)) -+#define BITMAP_FOR_EACH_1(IDX, SIZE, BITMAP) \ -+ BITMAP_FOR_EACH_1_RANGE(IDX, 0, SIZE, BITMAP) -+ -+/* More efficient access to a map of single ullong. */ -+#define ULLONG_FOR_EACH_1(IDX, MAP) \ -+ for (uint64_t map__ = (MAP); \ -+ map__ && (((IDX) = raw_ctz(map__)), true); \ -+ map__ = zero_rightmost_1bit(map__)) -+ -+#define ULLONG_SET0(MAP, OFFSET) ((MAP) &= ~(1ULL << (OFFSET))) -+#define ULLONG_SET1(MAP, OFFSET) ((MAP) |= 1ULL << (OFFSET)) -+ -+/* Returns the value of a bit in a map as a bool. */ -+#define ULLONG_GET(MAP, OFFSET) !!((MAP) & (1ULL << (OFFSET))) -+ -+#endif /* bitmap.h */ -Index: openvswitch-2.17.2/lib/classifier.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/classifier.h -+++ /dev/null -@@ -1,482 +0,0 @@ --/* -- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef CLASSIFIER_H --#define CLASSIFIER_H 1 -- --/* Flow classifier. -- * -- * -- * What? -- * ===== -- * -- * A flow classifier holds any number of "rules", each of which specifies -- * values to match for some fields or subfields and a priority. Each OpenFlow -- * table is implemented as a flow classifier. -- * -- * The classifier has two primary design goals. The first is obvious: given a -- * set of packet headers, as quickly as possible find the highest-priority rule -- * that matches those headers. The following section describes the second -- * goal. -- * -- * -- * "Un-wildcarding" -- * ================ -- * -- * A primary goal of the flow classifier is to produce, as a side effect of a -- * packet lookup, a wildcard mask that indicates which bits of the packet -- * headers were essential to the classification result. Ideally, a 1-bit in -- * any position of this mask means that, if the corresponding bit in the packet -- * header were flipped, then the classification result might change. A 0-bit -- * means that changing the packet header bit would have no effect. Thus, the -- * wildcarded bits are the ones that played no role in the classification -- * decision. -- * -- * Such a wildcard mask is useful with datapaths that support installing flows -- * that wildcard fields or subfields. If an OpenFlow lookup for a TCP flow -- * does not actually look at the TCP source or destination ports, for example, -- * then the switch may install into the datapath a flow that wildcards the port -- * numbers, which in turn allows the datapath to handle packets that arrive for -- * other TCP source or destination ports without additional help from -- * ovs-vswitchd. This is useful for the Open vSwitch software and, -- * potentially, for ASIC-based switches as well. -- * -- * Some properties of the wildcard mask: -- * -- * - "False 1-bits" are acceptable, that is, setting a bit in the wildcard -- * mask to 1 will never cause a packet to be forwarded the wrong way. -- * As a corollary, a wildcard mask composed of all 1-bits will always -- * yield correct (but often needlessly inefficient) behavior. -- * -- * - "False 0-bits" can cause problems, so they must be avoided. In the -- * extreme case, a mask of all 0-bits is only correct if the classifier -- * contains only a single flow that matches all packets. -- * -- * - 0-bits are desirable because they allow the datapath to act more -- * autonomously, relying less on ovs-vswitchd to process flow setups, -- * thereby improving performance. -- * -- * - We don't know a good way to generate wildcard masks with the maximum -- * (correct) number of 0-bits. We use various approximations, described -- * in later sections. -- * -- * - Wildcard masks for lookups in a given classifier yield a -- * non-overlapping set of rules. More specifically: -- * -- * Consider an classifier C1 filled with an arbitrary collection of rules -- * and an empty classifier C2. Now take a set of packet headers H and -- * look it up in C1, yielding a highest-priority matching rule R1 and -- * wildcard mask M. Form a new classifier rule R2 out of packet headers -- * H and mask M, and add R2 to C2 with a fixed priority. If one were to -- * do this for every possible set of packet headers H, then this -- * process would not attempt to add any overlapping rules to C2, that is, -- * any packet lookup using the rules generated by this process matches at -- * most one rule in C2. -- * -- * During the lookup process, the classifier starts out with a wildcard mask -- * that is all 0-bits, that is, fully wildcarded. As lookup proceeds, each -- * step tends to add constraints to the wildcard mask, that is, change -- * wildcarded 0-bits into exact-match 1-bits. We call this "un-wildcarding". -- * A lookup step that examines a particular field must un-wildcard that field. -- * In general, un-wildcarding is necessary for correctness but undesirable for -- * performance. -- * -- * -- * Basic Classifier Design -- * ======================= -- * -- * Suppose that all the rules in a classifier had the same form. For example, -- * suppose that they all matched on the source and destination Ethernet address -- * and wildcarded all the other fields. Then the obvious way to implement a -- * classifier would be a hash table on the source and destination Ethernet -- * addresses. If new classification rules came along with a different form, -- * you could add a second hash table that hashed on the fields matched in those -- * rules. With two hash tables, you look up a given flow in each hash table. -- * If there are no matches, the classifier didn't contain a match; if you find -- * a match in one of them, that's the result; if you find a match in both of -- * them, then the result is the rule with the higher priority. -- * -- * This is how the classifier works. In a "struct classifier", each form of -- * "struct cls_rule" present (based on its ->match.mask) goes into a separate -- * "struct cls_subtable". A lookup does a hash lookup in every "struct -- * cls_subtable" in the classifier and tracks the highest-priority match that -- * it finds. The subtables are kept in a descending priority order according -- * to the highest priority rule in each subtable, which allows lookup to skip -- * over subtables that can't possibly have a higher-priority match than already -- * found. Eliminating lookups through priority ordering aids both classifier -- * primary design goals: skipping lookups saves time and avoids un-wildcarding -- * fields that those lookups would have examined. -- * -- * One detail: a classifier can contain multiple rules that are identical other -- * than their priority. When this happens, only the highest priority rule out -- * of a group of otherwise identical rules is stored directly in the "struct -- * cls_subtable", with the other almost-identical rules chained off a linked -- * list inside that highest-priority rule. -- * -- * The following sub-sections describe various optimizations over this simple -- * approach. -- * -- * -- * Staged Lookup (Wildcard Optimization) -- * ------------------------------------- -- * -- * Subtable lookup is performed in ranges defined for struct flow, starting -- * from metadata (registers, in_port, etc.), then L2 header, L3, and finally -- * L4 ports. Whenever it is found that there are no matches in the current -- * subtable, the rest of the subtable can be skipped. -- * -- * Staged lookup does not reduce lookup time, and it may increase it, because -- * it changes a single hash table lookup into multiple hash table lookups. -- * It reduces un-wildcarding significantly in important use cases. -- * -- * -- * Prefix Tracking (Wildcard Optimization) -- * --------------------------------------- -- * -- * Classifier uses prefix trees ("tries") for tracking the used -- * address space, enabling skipping classifier tables containing -- * longer masks than necessary for the given address. This reduces -- * un-wildcarding for datapath flows in parts of the address space -- * without host routes, but consulting extra data structures (the -- * tries) may slightly increase lookup time. -- * -- * Trie lookup is interwoven with staged lookup, so that a trie is -- * searched only when the configured trie field becomes relevant for -- * the lookup. The trie lookup results are retained so that each trie -- * is checked at most once for each classifier lookup. -- * -- * This implementation tracks the number of rules at each address -- * prefix for the whole classifier. More aggressive table skipping -- * would be possible by maintaining lists of tables that have prefixes -- * at the lengths encountered on tree traversal, or by maintaining -- * separate tries for subsets of rules separated by metadata fields. -- * -- * Prefix tracking is configured via OVSDB "Flow_Table" table, -- * "fieldspec" column. "fieldspec" is a string map where a "prefix" -- * key tells which fields should be used for prefix tracking. The -- * value of the "prefix" key is a comma separated list of field names. -- * -- * There is a maximum number of fields that can be enabled for any one -- * flow table. Currently this limit is 3. -- * -- * -- * Partitioning (Lookup Time and Wildcard Optimization) -- * ---------------------------------------------------- -- * -- * Suppose that a given classifier is being used to handle multiple stages in a -- * pipeline using "resubmit", with metadata (that is, the OpenFlow 1.1+ field -- * named "metadata") distinguishing between the different stages. For example, -- * metadata value 1 might identify ingress rules, metadata value 2 might -- * identify ACLs, and metadata value 3 might identify egress rules. Such a -- * classifier is essentially partitioned into multiple sub-classifiers on the -- * basis of the metadata value. -- * -- * The classifier has a special optimization to speed up matching in this -- * scenario: -- * -- * - Each cls_subtable that matches on metadata gets a tag derived from the -- * subtable's mask, so that it is likely that each subtable has a unique -- * tag. (Duplicate tags have a performance cost but do not affect -- * correctness.) -- * -- * - For each metadata value matched by any cls_rule, the classifier -- * constructs a "struct cls_partition" indexed by the metadata value. -- * The cls_partition has a 'tags' member whose value is the bitwise-OR of -- * the tags of each cls_subtable that contains any rule that matches on -- * the cls_partition's metadata value. In other words, struct -- * cls_partition associates metadata values with subtables that need to -- * be checked with flows with that specific metadata value. -- * -- * Thus, a flow lookup can start by looking up the partition associated with -- * the flow's metadata, and then skip over any cls_subtable whose 'tag' does -- * not intersect the partition's 'tags'. (The flow must also be looked up in -- * any cls_subtable that doesn't match on metadata. We handle that by giving -- * any such cls_subtable TAG_ALL as its 'tags' so that it matches any tag.) -- * -- * Partitioning saves lookup time by reducing the number of subtable lookups. -- * Each eliminated subtable lookup also reduces the amount of un-wildcarding. -- * -- * -- * Classifier Versioning -- * ===================== -- * -- * Classifier lookups are always done in a specific classifier version, where -- * a version is defined to be a natural number. -- * -- * When a new rule is added to a classifier, it is set to become visible in a -- * specific version. If the version number used at insert time is larger than -- * any version number currently used in lookups, the new rule is said to be -- * invisible to lookups. This means that lookups won't find the rule, but the -- * rule is immediately available to classifier iterations. -- * -- * Similarly, a rule can be marked as to be deleted in a future version. To -- * delete a rule in a way to not remove the rule before all ongoing lookups are -- * finished, the rule should be made invisible in a specific version number. -- * Then, when all the lookups use a later version number, the rule can be -- * actually removed from the classifier. -- * -- * Classifiers can hold duplicate rules (rules with the same match criteria and -- * priority) when at most one of these duplicates is visible in any given -- * lookup version. The caller responsible for classifier modifications must -- * maintain this invariant. -- * -- * The classifier supports versioning for two reasons: -- * -- * 1. Support for versioned modifications makes it possible to perform an -- * arbitrary series of classifier changes as one atomic transaction, -- * where intermediate versions of the classifier are not visible to any -- * lookups. Also, when a rule is added for a future version, or marked -- * for removal after the current version, such modifications can be -- * reverted without any visible effects to any of the current lookups. -- * -- * 2. Performance: Adding (or deleting) a large set of rules can, in -- * pathological cases, have a cost proportional to the number of rules -- * already in the classifier. When multiple rules are being added (or -- * deleted) in one go, though, this pathological case cost can be -- * typically avoided, as long as it is OK for any new rules to be -- * invisible until the batch change is complete. -- * -- * Note that the classifier_replace() function replaces a rule immediately, and -- * is therefore not safe to use with versioning. It is still available for the -- * users that do not use versioning. -- * -- * -- * Deferred Publication -- * ==================== -- * -- * Removing large number of rules from classifier can be costly, as the -- * supporting data structures are teared down, in many cases just to be -- * re-instantiated right after. In the worst case, as when each rule has a -- * different match pattern (mask), the maintenance of the match patterns can -- * have cost O(N^2), where N is the number of different match patterns. To -- * alleviate this, the classifier supports a "deferred mode", in which changes -- * in internal data structures needed for future version lookups may not be -- * fully computed yet. The computation is finalized when the deferred mode is -- * turned off. -- * -- * This feature can be used with versioning such that all changes to future -- * versions are made in the deferred mode. Then, right before making the new -- * version visible to lookups, the deferred mode is turned off so that all the -- * data structures are ready for lookups with the new version number. -- * -- * To use deferred publication, first call classifier_defer(). Then, modify -- * the classifier via additions (classifier_insert() with a specific, future -- * version number) and deletions (use cls_rule_make_removable_after_version()). -- * Then call classifier_publish(), and after that, announce the new version -- * number to be used in lookups. -- * -- * -- * Thread-safety -- * ============= -- * -- * The classifier may safely be accessed by many reader threads concurrently -- * and by a single writer, or by multiple writers when they guarantee mutually -- * exclusive access to classifier modifications. -- * -- * Since the classifier rules are RCU protected, the rule destruction after -- * removal from the classifier must be RCU postponed. Also, when versioning is -- * used, the rule removal itself needs to be typically RCU postponed. In this -- * case the rule destruction is doubly RCU postponed, i.e., the second -- * ovsrcu_postpone() call to destruct the rule is called from the first RCU -- * callback that removes the rule. -- * -- * Rules that have never been visible to lookups are an exception to the above -- * rule. Such rules can be removed immediately, but their destruction must -- * still be RCU postponed, as the rule's visibility attribute may be examined -- * parallel to the rule's removal. */ -- --#include "cmap.h" --#include "openvswitch/match.h" --#include "openvswitch/meta-flow.h" --#include "pvector.h" --#include "rculist.h" --#include "openvswitch/type-props.h" --#include "versions.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --/* Classifier internal data structures. */ --struct cls_subtable; --struct cls_match; -- --struct mf_field; --typedef OVSRCU_TYPE(struct mf_field *) rcu_field_ptr; --struct trie_node; --typedef OVSRCU_TYPE(struct trie_node *) rcu_trie_ptr; -- --/* Prefix trie for a 'field' */ --struct cls_trie { -- rcu_field_ptr field; /* Trie field, or NULL. */ -- rcu_trie_ptr root; /* NULL if none. */ --}; -- --enum { -- CLS_MAX_INDICES = 3, /* Maximum number of lookup indices per subtable. */ -- CLS_MAX_TRIES = 3 /* Maximum number of prefix trees per classifier. */ --}; -- --/* A flow classifier. */ --struct classifier { -- int n_rules; /* Total number of rules. */ -- uint8_t n_flow_segments; -- uint8_t flow_segments[CLS_MAX_INDICES]; /* Flow segment boundaries to use -- * for staged lookup. */ -- struct cmap subtables_map; /* Contains "struct cls_subtable"s. */ -- struct pvector subtables; -- struct cmap partitions; /* Contains "struct cls_partition"s. */ -- struct cls_trie tries[CLS_MAX_TRIES]; /* Prefix tries. */ -- unsigned int n_tries; -- bool publish; /* Make changes visible to lookups? */ --}; -- --struct cls_conjunction { -- uint32_t id; -- uint8_t clause; -- uint8_t n_clauses; --}; -- --/* A rule to be inserted to the classifier. */ --struct cls_rule { -- struct rculist node; /* In struct cls_subtable 'rules_list'. */ -- const int priority; /* Larger numbers are higher priorities. */ -- OVSRCU_TYPE(struct cls_match *) cls_match; /* NULL if not in a -- * classifier. */ -- const struct minimatch match; /* Matching rule. */ --}; -- --/* Constructor/destructor. Must run single-threaded. */ --void classifier_init(struct classifier *, const uint8_t *flow_segments); --void classifier_destroy(struct classifier *); -- --/* Modifiers. Caller MUST exclude concurrent calls from other threads. */ --bool classifier_set_prefix_fields(struct classifier *, -- const enum mf_field_id *trie_fields, -- unsigned int n_trie_fields); -- --void cls_rule_init(struct cls_rule *, const struct match *, int priority); --void cls_rule_init_from_minimatch(struct cls_rule *, const struct minimatch *, -- int priority); --void cls_rule_clone(struct cls_rule *, const struct cls_rule *); --void cls_rule_move(struct cls_rule *dst, struct cls_rule *src); --void cls_rule_destroy(struct cls_rule *); -- --void cls_rule_set_conjunctions(struct cls_rule *, -- const struct cls_conjunction *, size_t n); --void cls_rule_make_invisible_in_version(const struct cls_rule *, -- ovs_version_t); --void cls_rule_restore_visibility(const struct cls_rule *); -- --void classifier_insert(struct classifier *, const struct cls_rule *, -- ovs_version_t, const struct cls_conjunction *, -- size_t n_conjunctions); --const struct cls_rule *classifier_replace(struct classifier *, -- const struct cls_rule *, -- ovs_version_t, -- const struct cls_conjunction *, -- size_t n_conjunctions); --bool classifier_remove(struct classifier *, const struct cls_rule *); --void classifier_remove_assert(struct classifier *, const struct cls_rule *); --static inline void classifier_defer(struct classifier *); --static inline void classifier_publish(struct classifier *); -- --/* Lookups. These are RCU protected and may run concurrently with modifiers -- * and each other. */ --const struct cls_rule *classifier_lookup(const struct classifier *, -- ovs_version_t, struct flow *, -- struct flow_wildcards *); --bool classifier_rule_overlaps(const struct classifier *, -- const struct cls_rule *, ovs_version_t); --const struct cls_rule *classifier_find_rule_exactly(const struct classifier *, -- const struct cls_rule *, -- ovs_version_t); --const struct cls_rule *classifier_find_match_exactly(const struct classifier *, -- const struct match *, -- int priority, -- ovs_version_t); --const struct cls_rule *classifier_find_minimatch_exactly( -- const struct classifier *, const struct minimatch *, -- int priority, ovs_version_t); -- --bool classifier_is_empty(const struct classifier *); --int classifier_count(const struct classifier *); -- --/* Classifier rule properties. These are RCU protected and may run -- * concurrently with modifiers and each other. */ --bool cls_rule_equal(const struct cls_rule *, const struct cls_rule *); --void cls_rule_format(const struct cls_rule *, const struct tun_table *, -- const struct ofputil_port_map *, struct ds *); --bool cls_rule_is_catchall(const struct cls_rule *); --bool cls_rule_is_loose_match(const struct cls_rule *rule, -- const struct minimatch *criteria); --bool cls_rule_visible_in_version(const struct cls_rule *, ovs_version_t); -- --/* Iteration. -- * -- * Iteration is lockless and RCU-protected. Concurrent threads may perform all -- * kinds of concurrent modifications without ruining the iteration. Obviously, -- * any modifications may or may not be visible to the concurrent iterator, but -- * all the rules not deleted are visited by the iteration. The iterating -- * thread may also modify the classifier rules itself. -- * -- * 'TARGET' iteration only iterates rules matching the 'TARGET' criteria. -- * Rather than looping through all the rules and skipping ones that can't -- * match, 'TARGET' iteration skips whole subtables, if the 'TARGET' happens to -- * be more specific than the subtable. */ --struct cls_cursor { -- const struct classifier *cls; -- const struct cls_subtable *subtable; -- const struct cls_rule *target; -- ovs_version_t version; /* Version to iterate. */ -- struct pvector_cursor subtables; -- const struct cls_rule *rule; --}; -- --struct cls_cursor cls_cursor_start(const struct classifier *, -- const struct cls_rule *target, -- ovs_version_t); --void cls_cursor_advance(struct cls_cursor *); -- --#define CLS_FOR_EACH(RULE, MEMBER, CLS) \ -- CLS_FOR_EACH_TARGET(RULE, MEMBER, CLS, NULL, OVS_VERSION_MAX) --#define CLS_FOR_EACH_TARGET(RULE, MEMBER, CLS, TARGET, VERSION) \ -- for (struct cls_cursor cursor__ = cls_cursor_start(CLS, TARGET, VERSION); \ -- (cursor__.rule \ -- ? (INIT_CONTAINER(RULE, cursor__.rule, MEMBER), \ -- cls_cursor_advance(&cursor__), \ -- true) \ -- : false); \ -- ) -- -- --static inline void --classifier_defer(struct classifier *cls) --{ -- cls->publish = false; --} -- --static inline void --classifier_publish(struct classifier *cls) --{ -- cls->publish = true; -- pvector_publish(&cls->subtables); --} -- --#ifdef __cplusplus --} --#endif --#endif /* classifier.h */ -Index: openvswitch-2.17.2/include/internal/classifier.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/classifier.h -@@ -0,0 +1,482 @@ -+/* -+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef CLASSIFIER_H -+#define CLASSIFIER_H 1 -+ -+/* Flow classifier. -+ * -+ * -+ * What? -+ * ===== -+ * -+ * A flow classifier holds any number of "rules", each of which specifies -+ * values to match for some fields or subfields and a priority. Each OpenFlow -+ * table is implemented as a flow classifier. -+ * -+ * The classifier has two primary design goals. The first is obvious: given a -+ * set of packet headers, as quickly as possible find the highest-priority rule -+ * that matches those headers. The following section describes the second -+ * goal. -+ * -+ * -+ * "Un-wildcarding" -+ * ================ -+ * -+ * A primary goal of the flow classifier is to produce, as a side effect of a -+ * packet lookup, a wildcard mask that indicates which bits of the packet -+ * headers were essential to the classification result. Ideally, a 1-bit in -+ * any position of this mask means that, if the corresponding bit in the packet -+ * header were flipped, then the classification result might change. A 0-bit -+ * means that changing the packet header bit would have no effect. Thus, the -+ * wildcarded bits are the ones that played no role in the classification -+ * decision. -+ * -+ * Such a wildcard mask is useful with datapaths that support installing flows -+ * that wildcard fields or subfields. If an OpenFlow lookup for a TCP flow -+ * does not actually look at the TCP source or destination ports, for example, -+ * then the switch may install into the datapath a flow that wildcards the port -+ * numbers, which in turn allows the datapath to handle packets that arrive for -+ * other TCP source or destination ports without additional help from -+ * ovs-vswitchd. This is useful for the Open vSwitch software and, -+ * potentially, for ASIC-based switches as well. -+ * -+ * Some properties of the wildcard mask: -+ * -+ * - "False 1-bits" are acceptable, that is, setting a bit in the wildcard -+ * mask to 1 will never cause a packet to be forwarded the wrong way. -+ * As a corollary, a wildcard mask composed of all 1-bits will always -+ * yield correct (but often needlessly inefficient) behavior. -+ * -+ * - "False 0-bits" can cause problems, so they must be avoided. In the -+ * extreme case, a mask of all 0-bits is only correct if the classifier -+ * contains only a single flow that matches all packets. -+ * -+ * - 0-bits are desirable because they allow the datapath to act more -+ * autonomously, relying less on ovs-vswitchd to process flow setups, -+ * thereby improving performance. -+ * -+ * - We don't know a good way to generate wildcard masks with the maximum -+ * (correct) number of 0-bits. We use various approximations, described -+ * in later sections. -+ * -+ * - Wildcard masks for lookups in a given classifier yield a -+ * non-overlapping set of rules. More specifically: -+ * -+ * Consider an classifier C1 filled with an arbitrary collection of rules -+ * and an empty classifier C2. Now take a set of packet headers H and -+ * look it up in C1, yielding a highest-priority matching rule R1 and -+ * wildcard mask M. Form a new classifier rule R2 out of packet headers -+ * H and mask M, and add R2 to C2 with a fixed priority. If one were to -+ * do this for every possible set of packet headers H, then this -+ * process would not attempt to add any overlapping rules to C2, that is, -+ * any packet lookup using the rules generated by this process matches at -+ * most one rule in C2. -+ * -+ * During the lookup process, the classifier starts out with a wildcard mask -+ * that is all 0-bits, that is, fully wildcarded. As lookup proceeds, each -+ * step tends to add constraints to the wildcard mask, that is, change -+ * wildcarded 0-bits into exact-match 1-bits. We call this "un-wildcarding". -+ * A lookup step that examines a particular field must un-wildcard that field. -+ * In general, un-wildcarding is necessary for correctness but undesirable for -+ * performance. -+ * -+ * -+ * Basic Classifier Design -+ * ======================= -+ * -+ * Suppose that all the rules in a classifier had the same form. For example, -+ * suppose that they all matched on the source and destination Ethernet address -+ * and wildcarded all the other fields. Then the obvious way to implement a -+ * classifier would be a hash table on the source and destination Ethernet -+ * addresses. If new classification rules came along with a different form, -+ * you could add a second hash table that hashed on the fields matched in those -+ * rules. With two hash tables, you look up a given flow in each hash table. -+ * If there are no matches, the classifier didn't contain a match; if you find -+ * a match in one of them, that's the result; if you find a match in both of -+ * them, then the result is the rule with the higher priority. -+ * -+ * This is how the classifier works. In a "struct classifier", each form of -+ * "struct cls_rule" present (based on its ->match.mask) goes into a separate -+ * "struct cls_subtable". A lookup does a hash lookup in every "struct -+ * cls_subtable" in the classifier and tracks the highest-priority match that -+ * it finds. The subtables are kept in a descending priority order according -+ * to the highest priority rule in each subtable, which allows lookup to skip -+ * over subtables that can't possibly have a higher-priority match than already -+ * found. Eliminating lookups through priority ordering aids both classifier -+ * primary design goals: skipping lookups saves time and avoids un-wildcarding -+ * fields that those lookups would have examined. -+ * -+ * One detail: a classifier can contain multiple rules that are identical other -+ * than their priority. When this happens, only the highest priority rule out -+ * of a group of otherwise identical rules is stored directly in the "struct -+ * cls_subtable", with the other almost-identical rules chained off a linked -+ * list inside that highest-priority rule. -+ * -+ * The following sub-sections describe various optimizations over this simple -+ * approach. -+ * -+ * -+ * Staged Lookup (Wildcard Optimization) -+ * ------------------------------------- -+ * -+ * Subtable lookup is performed in ranges defined for struct flow, starting -+ * from metadata (registers, in_port, etc.), then L2 header, L3, and finally -+ * L4 ports. Whenever it is found that there are no matches in the current -+ * subtable, the rest of the subtable can be skipped. -+ * -+ * Staged lookup does not reduce lookup time, and it may increase it, because -+ * it changes a single hash table lookup into multiple hash table lookups. -+ * It reduces un-wildcarding significantly in important use cases. -+ * -+ * -+ * Prefix Tracking (Wildcard Optimization) -+ * --------------------------------------- -+ * -+ * Classifier uses prefix trees ("tries") for tracking the used -+ * address space, enabling skipping classifier tables containing -+ * longer masks than necessary for the given address. This reduces -+ * un-wildcarding for datapath flows in parts of the address space -+ * without host routes, but consulting extra data structures (the -+ * tries) may slightly increase lookup time. -+ * -+ * Trie lookup is interwoven with staged lookup, so that a trie is -+ * searched only when the configured trie field becomes relevant for -+ * the lookup. The trie lookup results are retained so that each trie -+ * is checked at most once for each classifier lookup. -+ * -+ * This implementation tracks the number of rules at each address -+ * prefix for the whole classifier. More aggressive table skipping -+ * would be possible by maintaining lists of tables that have prefixes -+ * at the lengths encountered on tree traversal, or by maintaining -+ * separate tries for subsets of rules separated by metadata fields. -+ * -+ * Prefix tracking is configured via OVSDB "Flow_Table" table, -+ * "fieldspec" column. "fieldspec" is a string map where a "prefix" -+ * key tells which fields should be used for prefix tracking. The -+ * value of the "prefix" key is a comma separated list of field names. -+ * -+ * There is a maximum number of fields that can be enabled for any one -+ * flow table. Currently this limit is 3. -+ * -+ * -+ * Partitioning (Lookup Time and Wildcard Optimization) -+ * ---------------------------------------------------- -+ * -+ * Suppose that a given classifier is being used to handle multiple stages in a -+ * pipeline using "resubmit", with metadata (that is, the OpenFlow 1.1+ field -+ * named "metadata") distinguishing between the different stages. For example, -+ * metadata value 1 might identify ingress rules, metadata value 2 might -+ * identify ACLs, and metadata value 3 might identify egress rules. Such a -+ * classifier is essentially partitioned into multiple sub-classifiers on the -+ * basis of the metadata value. -+ * -+ * The classifier has a special optimization to speed up matching in this -+ * scenario: -+ * -+ * - Each cls_subtable that matches on metadata gets a tag derived from the -+ * subtable's mask, so that it is likely that each subtable has a unique -+ * tag. (Duplicate tags have a performance cost but do not affect -+ * correctness.) -+ * -+ * - For each metadata value matched by any cls_rule, the classifier -+ * constructs a "struct cls_partition" indexed by the metadata value. -+ * The cls_partition has a 'tags' member whose value is the bitwise-OR of -+ * the tags of each cls_subtable that contains any rule that matches on -+ * the cls_partition's metadata value. In other words, struct -+ * cls_partition associates metadata values with subtables that need to -+ * be checked with flows with that specific metadata value. -+ * -+ * Thus, a flow lookup can start by looking up the partition associated with -+ * the flow's metadata, and then skip over any cls_subtable whose 'tag' does -+ * not intersect the partition's 'tags'. (The flow must also be looked up in -+ * any cls_subtable that doesn't match on metadata. We handle that by giving -+ * any such cls_subtable TAG_ALL as its 'tags' so that it matches any tag.) -+ * -+ * Partitioning saves lookup time by reducing the number of subtable lookups. -+ * Each eliminated subtable lookup also reduces the amount of un-wildcarding. -+ * -+ * -+ * Classifier Versioning -+ * ===================== -+ * -+ * Classifier lookups are always done in a specific classifier version, where -+ * a version is defined to be a natural number. -+ * -+ * When a new rule is added to a classifier, it is set to become visible in a -+ * specific version. If the version number used at insert time is larger than -+ * any version number currently used in lookups, the new rule is said to be -+ * invisible to lookups. This means that lookups won't find the rule, but the -+ * rule is immediately available to classifier iterations. -+ * -+ * Similarly, a rule can be marked as to be deleted in a future version. To -+ * delete a rule in a way to not remove the rule before all ongoing lookups are -+ * finished, the rule should be made invisible in a specific version number. -+ * Then, when all the lookups use a later version number, the rule can be -+ * actually removed from the classifier. -+ * -+ * Classifiers can hold duplicate rules (rules with the same match criteria and -+ * priority) when at most one of these duplicates is visible in any given -+ * lookup version. The caller responsible for classifier modifications must -+ * maintain this invariant. -+ * -+ * The classifier supports versioning for two reasons: -+ * -+ * 1. Support for versioned modifications makes it possible to perform an -+ * arbitrary series of classifier changes as one atomic transaction, -+ * where intermediate versions of the classifier are not visible to any -+ * lookups. Also, when a rule is added for a future version, or marked -+ * for removal after the current version, such modifications can be -+ * reverted without any visible effects to any of the current lookups. -+ * -+ * 2. Performance: Adding (or deleting) a large set of rules can, in -+ * pathological cases, have a cost proportional to the number of rules -+ * already in the classifier. When multiple rules are being added (or -+ * deleted) in one go, though, this pathological case cost can be -+ * typically avoided, as long as it is OK for any new rules to be -+ * invisible until the batch change is complete. -+ * -+ * Note that the classifier_replace() function replaces a rule immediately, and -+ * is therefore not safe to use with versioning. It is still available for the -+ * users that do not use versioning. -+ * -+ * -+ * Deferred Publication -+ * ==================== -+ * -+ * Removing large number of rules from classifier can be costly, as the -+ * supporting data structures are teared down, in many cases just to be -+ * re-instantiated right after. In the worst case, as when each rule has a -+ * different match pattern (mask), the maintenance of the match patterns can -+ * have cost O(N^2), where N is the number of different match patterns. To -+ * alleviate this, the classifier supports a "deferred mode", in which changes -+ * in internal data structures needed for future version lookups may not be -+ * fully computed yet. The computation is finalized when the deferred mode is -+ * turned off. -+ * -+ * This feature can be used with versioning such that all changes to future -+ * versions are made in the deferred mode. Then, right before making the new -+ * version visible to lookups, the deferred mode is turned off so that all the -+ * data structures are ready for lookups with the new version number. -+ * -+ * To use deferred publication, first call classifier_defer(). Then, modify -+ * the classifier via additions (classifier_insert() with a specific, future -+ * version number) and deletions (use cls_rule_make_removable_after_version()). -+ * Then call classifier_publish(), and after that, announce the new version -+ * number to be used in lookups. -+ * -+ * -+ * Thread-safety -+ * ============= -+ * -+ * The classifier may safely be accessed by many reader threads concurrently -+ * and by a single writer, or by multiple writers when they guarantee mutually -+ * exclusive access to classifier modifications. -+ * -+ * Since the classifier rules are RCU protected, the rule destruction after -+ * removal from the classifier must be RCU postponed. Also, when versioning is -+ * used, the rule removal itself needs to be typically RCU postponed. In this -+ * case the rule destruction is doubly RCU postponed, i.e., the second -+ * ovsrcu_postpone() call to destruct the rule is called from the first RCU -+ * callback that removes the rule. -+ * -+ * Rules that have never been visible to lookups are an exception to the above -+ * rule. Such rules can be removed immediately, but their destruction must -+ * still be RCU postponed, as the rule's visibility attribute may be examined -+ * parallel to the rule's removal. */ -+ -+#include "internal/cmap.h" -+#include "openvswitch/match.h" -+#include "openvswitch/meta-flow.h" -+#include "internal/pvector.h" -+#include "internal/rculist.h" -+#include "openvswitch/type-props.h" -+#include "internal/versions.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Classifier internal data structures. */ -+struct cls_subtable; -+struct cls_match; -+ -+struct mf_field; -+typedef OVSRCU_TYPE(struct mf_field *) rcu_field_ptr; -+struct trie_node; -+typedef OVSRCU_TYPE(struct trie_node *) rcu_trie_ptr; -+ -+/* Prefix trie for a 'field' */ -+struct cls_trie { -+ rcu_field_ptr field; /* Trie field, or NULL. */ -+ rcu_trie_ptr root; /* NULL if none. */ -+}; -+ -+enum { -+ CLS_MAX_INDICES = 3, /* Maximum number of lookup indices per subtable. */ -+ CLS_MAX_TRIES = 3 /* Maximum number of prefix trees per classifier. */ -+}; -+ -+/* A flow classifier. */ -+struct classifier { -+ int n_rules; /* Total number of rules. */ -+ uint8_t n_flow_segments; -+ uint8_t flow_segments[CLS_MAX_INDICES]; /* Flow segment boundaries to use -+ * for staged lookup. */ -+ struct cmap subtables_map; /* Contains "struct cls_subtable"s. */ -+ struct pvector subtables; -+ struct cmap partitions; /* Contains "struct cls_partition"s. */ -+ struct cls_trie tries[CLS_MAX_TRIES]; /* Prefix tries. */ -+ unsigned int n_tries; -+ bool publish; /* Make changes visible to lookups? */ -+}; -+ -+struct cls_conjunction { -+ uint32_t id; -+ uint8_t clause; -+ uint8_t n_clauses; -+}; -+ -+/* A rule to be inserted to the classifier. */ -+struct cls_rule { -+ struct rculist node; /* In struct cls_subtable 'rules_list'. */ -+ const int priority; /* Larger numbers are higher priorities. */ -+ OVSRCU_TYPE(struct cls_match *) cls_match; /* NULL if not in a -+ * classifier. */ -+ const struct minimatch match; /* Matching rule. */ -+}; -+ -+/* Constructor/destructor. Must run single-threaded. */ -+void classifier_init(struct classifier *, const uint8_t *flow_segments); -+void classifier_destroy(struct classifier *); -+ -+/* Modifiers. Caller MUST exclude concurrent calls from other threads. */ -+bool classifier_set_prefix_fields(struct classifier *, -+ const enum mf_field_id *trie_fields, -+ unsigned int n_trie_fields); -+ -+void cls_rule_init(struct cls_rule *, const struct match *, int priority); -+void cls_rule_init_from_minimatch(struct cls_rule *, const struct minimatch *, -+ int priority); -+void cls_rule_clone(struct cls_rule *, const struct cls_rule *); -+void cls_rule_move(struct cls_rule *dst, struct cls_rule *src); -+void cls_rule_destroy(struct cls_rule *); -+ -+void cls_rule_set_conjunctions(struct cls_rule *, -+ const struct cls_conjunction *, size_t n); -+void cls_rule_make_invisible_in_version(const struct cls_rule *, -+ ovs_version_t); -+void cls_rule_restore_visibility(const struct cls_rule *); -+ -+void classifier_insert(struct classifier *, const struct cls_rule *, -+ ovs_version_t, const struct cls_conjunction *, -+ size_t n_conjunctions); -+const struct cls_rule *classifier_replace(struct classifier *, -+ const struct cls_rule *, -+ ovs_version_t, -+ const struct cls_conjunction *, -+ size_t n_conjunctions); -+bool classifier_remove(struct classifier *, const struct cls_rule *); -+void classifier_remove_assert(struct classifier *, const struct cls_rule *); -+static inline void classifier_defer(struct classifier *); -+static inline void classifier_publish(struct classifier *); -+ -+/* Lookups. These are RCU protected and may run concurrently with modifiers -+ * and each other. */ -+const struct cls_rule *classifier_lookup(const struct classifier *, -+ ovs_version_t, struct flow *, -+ struct flow_wildcards *); -+bool classifier_rule_overlaps(const struct classifier *, -+ const struct cls_rule *, ovs_version_t); -+const struct cls_rule *classifier_find_rule_exactly(const struct classifier *, -+ const struct cls_rule *, -+ ovs_version_t); -+const struct cls_rule *classifier_find_match_exactly(const struct classifier *, -+ const struct match *, -+ int priority, -+ ovs_version_t); -+const struct cls_rule *classifier_find_minimatch_exactly( -+ const struct classifier *, const struct minimatch *, -+ int priority, ovs_version_t); -+ -+bool classifier_is_empty(const struct classifier *); -+int classifier_count(const struct classifier *); -+ -+/* Classifier rule properties. These are RCU protected and may run -+ * concurrently with modifiers and each other. */ -+bool cls_rule_equal(const struct cls_rule *, const struct cls_rule *); -+void cls_rule_format(const struct cls_rule *, const struct tun_table *, -+ const struct ofputil_port_map *, struct ds *); -+bool cls_rule_is_catchall(const struct cls_rule *); -+bool cls_rule_is_loose_match(const struct cls_rule *rule, -+ const struct minimatch *criteria); -+bool cls_rule_visible_in_version(const struct cls_rule *, ovs_version_t); -+ -+/* Iteration. -+ * -+ * Iteration is lockless and RCU-protected. Concurrent threads may perform all -+ * kinds of concurrent modifications without ruining the iteration. Obviously, -+ * any modifications may or may not be visible to the concurrent iterator, but -+ * all the rules not deleted are visited by the iteration. The iterating -+ * thread may also modify the classifier rules itself. -+ * -+ * 'TARGET' iteration only iterates rules matching the 'TARGET' criteria. -+ * Rather than looping through all the rules and skipping ones that can't -+ * match, 'TARGET' iteration skips whole subtables, if the 'TARGET' happens to -+ * be more specific than the subtable. */ -+struct cls_cursor { -+ const struct classifier *cls; -+ const struct cls_subtable *subtable; -+ const struct cls_rule *target; -+ ovs_version_t version; /* Version to iterate. */ -+ struct pvector_cursor subtables; -+ const struct cls_rule *rule; -+}; -+ -+struct cls_cursor cls_cursor_start(const struct classifier *, -+ const struct cls_rule *target, -+ ovs_version_t); -+void cls_cursor_advance(struct cls_cursor *); -+ -+#define CLS_FOR_EACH(RULE, MEMBER, CLS) \ -+ CLS_FOR_EACH_TARGET(RULE, MEMBER, CLS, NULL, OVS_VERSION_MAX) -+#define CLS_FOR_EACH_TARGET(RULE, MEMBER, CLS, TARGET, VERSION) \ -+ for (struct cls_cursor cursor__ = cls_cursor_start(CLS, TARGET, VERSION); \ -+ (cursor__.rule \ -+ ? (INIT_CONTAINER(RULE, cursor__.rule, MEMBER), \ -+ cls_cursor_advance(&cursor__), \ -+ true) \ -+ : false); \ -+ ) -+ -+ -+static inline void -+classifier_defer(struct classifier *cls) -+{ -+ cls->publish = false; -+} -+ -+static inline void -+classifier_publish(struct classifier *cls) -+{ -+ cls->publish = true; -+ pvector_publish(&cls->subtables); -+} -+ -+#ifdef __cplusplus -+} -+#endif -+#endif /* classifier.h */ -Index: openvswitch-2.17.2/lib/cmap.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/cmap.h -+++ /dev/null -@@ -1,297 +0,0 @@ --/* -- * Copyright (c) 2014, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef CMAP_H --#define CMAP_H 1 -- --#include --#include --#include "ovs-rcu.h" --#include "util.h" -- --/* Concurrent hash map -- * =================== -- * -- * A single-writer, multiple-reader hash table that efficiently supports -- * duplicates. -- * -- * -- * Thread-safety -- * ============= -- * -- * The general rules are: -- * -- * - Only a single thread may safely call into cmap_insert(), -- * cmap_remove(), or cmap_replace() at any given time. -- * -- * - Any number of threads may use functions and macros that search or -- * iterate through a given cmap, even in parallel with other threads -- * calling cmap_insert(), cmap_remove(), or cmap_replace(). -- * -- * There is one exception: cmap_find_protected() is only safe if no thread -- * is currently calling cmap_insert(), cmap_remove(), or cmap_replace(). -- * (Use ordinary cmap_find() if that is not guaranteed.) -- * -- * - See "Iteration" below for additional thread safety rules. -- * -- * Writers must use special care to ensure that any elements that they remove -- * do not get freed or reused until readers have finished with them. This -- * includes inserting the element back into its original cmap or a different -- * one. One correct way to do this is to free them from an RCU callback with -- * ovsrcu_postpone(). -- */ -- --/* A concurrent hash map node, to be embedded inside the data structure being -- * mapped. -- * -- * All nodes linked together on a chain have exactly the same hash value. */ --struct cmap_node { -- OVSRCU_TYPE(struct cmap_node *) next; /* Next node with same hash. */ --}; -- --static inline struct cmap_node * --cmap_node_next(const struct cmap_node *node) --{ -- return ovsrcu_get(struct cmap_node *, &node->next); --} -- --static inline struct cmap_node * --cmap_node_next_protected(const struct cmap_node *node) --{ -- return ovsrcu_get_protected(struct cmap_node *, &node->next); --} -- --/* Concurrent hash map. */ --struct cmap { -- OVSRCU_TYPE(struct cmap_impl *) impl; --}; -- --/* Initializer for an empty cmap. */ --#define CMAP_INITIALIZER { \ -- .impl = OVSRCU_INITIALIZER((struct cmap_impl *) &empty_cmap) \ -- } --extern OVS_ALIGNED_VAR(CACHE_LINE_SIZE) const struct cmap_impl empty_cmap; -- --/* Initialization. */ --void cmap_init(struct cmap *); --void cmap_destroy(struct cmap *); -- --/* Count. */ --size_t cmap_count(const struct cmap *); --bool cmap_is_empty(const struct cmap *); -- --/* Insertion and deletion. Return the current count after the operation. */ --size_t cmap_insert(struct cmap *, struct cmap_node *, uint32_t hash); --static inline size_t cmap_remove(struct cmap *, struct cmap_node *, -- uint32_t hash); --size_t cmap_replace(struct cmap *, struct cmap_node *old_node, -- struct cmap_node *new_node, uint32_t hash); -- --/* Search. -- * -- * These macros iterate NODE over all of the nodes in CMAP that have hash value -- * equal to HASH. MEMBER must be the name of the 'struct cmap_node' member -- * within NODE. -- * -- * CMAP and HASH are evaluated only once. NODE is evaluated many times. -- * -- * After a normal exit of the loop (not through a "break;" statement) NODE is -- * NULL. -- * -- * Thread-safety -- * ============= -- * -- * CMAP_NODE_FOR_EACH will reliably visit each of the nodes starting with -- * CMAP_NODE, even with concurrent insertions and deletions. (Of -- * course, if nodes are being inserted or deleted, it might or might not visit -- * the nodes actually being inserted or deleted.) -- * -- * CMAP_NODE_FOR_EACH_PROTECTED may only be used if the containing CMAP is -- * guaranteed not to change during iteration. It may be only slightly faster. -- * -- * CMAP_FOR_EACH_WITH_HASH will reliably visit each of the nodes with the -- * specified hash in CMAP, even with concurrent insertions and deletions. (Of -- * course, if nodes with the given HASH are being inserted or deleted, it might -- * or might not visit the nodes actually being inserted or deleted.) -- * -- * CMAP_FOR_EACH_WITH_HASH_PROTECTED may only be used if CMAP is guaranteed not -- * to change during iteration. It may be very slightly faster. -- */ --#define CMAP_NODE_FOR_EACH(NODE, MEMBER, CMAP_NODE) \ -- for (INIT_MULTIVAR(NODE, MEMBER, CMAP_NODE, struct cmap_node); \ -- CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -- UPDATE_MULTIVAR(NODE, cmap_node_next(ITER_VAR(NODE)))) --#define CMAP_NODE_FOR_EACH_PROTECTED(NODE, MEMBER, CMAP_NODE) \ -- for (INIT_MULTIVAR(NODE, MEMBER, CMAP_NODE, struct cmap_node); \ -- CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -- UPDATE_MULTIVAR(NODE, cmap_node_next_protected(ITER_VAR(NODE)))) -- --#define CMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, CMAP) \ -- CMAP_NODE_FOR_EACH(NODE, MEMBER, cmap_find(CMAP, HASH)) --#define CMAP_FOR_EACH_WITH_HASH_PROTECTED(NODE, MEMBER, HASH, CMAP) \ -- CMAP_NODE_FOR_EACH_PROTECTED(NODE, MEMBER, cmap_find_protected(CMAP, HASH)) -- --const struct cmap_node *cmap_find(const struct cmap *, uint32_t hash); --struct cmap_node *cmap_find_protected(const struct cmap *, uint32_t hash); -- --/* Find node by index or find index by hash. The 'index' of a cmap entry is a -- * way to combine the specific bucket and the entry of the bucket into a -- * convenient single integer value. In other words, it is the index of the -- * entry and each entry has an unique index. It is not used internally by -- * cmap. -- * Currently the functions assume index will not be larger than uint32_t. In -- * OvS table size is usually much smaller than this size.*/ --const struct cmap_node * cmap_find_by_index(const struct cmap *, -- uint32_t index); --uint32_t cmap_find_index(const struct cmap *, uint32_t hash); -- --/* Looks up multiple 'hashes', when the corresponding bit in 'map' is 1, -- * and sets the corresponding pointer in 'nodes', if the hash value was -- * found from the 'cmap'. In other cases the 'nodes' values are not changed, -- * i.e., no NULL pointers are stored there. -- * Returns a map where a bit is set to 1 if the corresponding 'nodes' pointer -- * was stored, 0 otherwise. -- * Generally, the caller wants to use CMAP_NODE_FOR_EACH to verify for -- * hash collisions. */ --unsigned long cmap_find_batch(const struct cmap *cmap, unsigned long map, -- uint32_t hashes[], -- const struct cmap_node *nodes[]); -- --/* Iteration. -- * -- * -- * Thread-safety -- * ============= -- * -- * Iteration is safe even in a cmap that is changing concurrently. However: -- * -- * - In the presence of concurrent calls to cmap_insert(), any given -- * iteration might skip some nodes and might visit some nodes more than -- * once. If this is a problem, then the iterating code should lock the -- * data structure (a rwlock can be used to allow multiple threads to -- * iterate in parallel). -- * -- * - Concurrent calls to cmap_remove() don't have the same problem. (A -- * node being deleted may be visited once or not at all. Other nodes -- * will be visited once.) -- * -- * - If the cmap is changing, it is not safe to quiesce while iterating. -- * Even if the changes are done by the same thread that's performing the -- * iteration (Corollary: it is not safe to call cmap_remove() and quiesce -- * in the loop body). -- * -- * -- * Example -- * ======= -- * -- * struct my_node { -- * struct cmap_node cmap_node; -- * int extra_data; -- * }; -- * -- * struct cmap my_map; -- * struct my_node *my_node; -- * -- * cmap_init(&my_map); -- * ...add data... -- * CMAP_FOR_EACH (my_node, cmap_node, &my_map) { -- * ...operate on my_node... -- * } -- * -- * CMAP_FOR_EACH is "safe" in the sense of HMAP_FOR_EACH_SAFE. That is, it is -- * safe to free the current node before going on to the next iteration. Most -- * of the time, though, this doesn't matter for a cmap because node -- * deallocation has to be postponed until the next grace period. This means -- * that this guarantee is useful only in deallocation code already executing at -- * postponed time, when it is known that the RCU grace period has already -- * expired. -- */ -- --#define CMAP_CURSOR_FOR_EACH__(NODE, CURSOR, MEMBER) \ -- ((CURSOR)->node \ -- ? (INIT_CONTAINER(NODE, (CURSOR)->node, MEMBER), \ -- cmap_cursor_advance(CURSOR), \ -- true) \ -- : (NODE = NULL, false)) -- --#define CMAP_CURSOR_FOR_EACH(NODE, MEMBER, CURSOR, CMAP) \ -- for (*(CURSOR) = cmap_cursor_start(CMAP); \ -- CMAP_CURSOR_FOR_EACH__(NODE, CURSOR, MEMBER); \ -- ) -- --#define CMAP_CURSOR_FOR_EACH_CONTINUE(NODE, MEMBER, CURSOR) \ -- while (CMAP_CURSOR_FOR_EACH__(NODE, CURSOR, MEMBER)) -- --struct cmap_cursor { -- const struct cmap_impl *impl; -- uint32_t bucket_idx; -- int entry_idx; -- struct cmap_node *node; --}; -- --struct cmap_cursor cmap_cursor_start(const struct cmap *); --void cmap_cursor_advance(struct cmap_cursor *); -- --/* Generate a unique name for the cursor with the __COUNTER__ macro to -- * allow nesting of CMAP_FOR_EACH loops. */ --#define CMAP_FOR_EACH__(NODE, MEMBER, CMAP, CURSOR_NAME) \ -- for (struct cmap_cursor CURSOR_NAME = cmap_cursor_start(CMAP); \ -- CMAP_CURSOR_FOR_EACH__(NODE, &CURSOR_NAME, MEMBER); \ -- ) -- --#define CMAP_FOR_EACH(NODE, MEMBER, CMAP) \ -- CMAP_FOR_EACH__(NODE, MEMBER, CMAP, \ -- OVS_JOIN(cursor_, __COUNTER__)) -- --static inline struct cmap_node *cmap_first(const struct cmap *); -- --/* Another, less preferred, form of iteration, for use in situations where it -- * is difficult to maintain a pointer to a cmap_node. */ --struct cmap_position { -- unsigned int bucket; -- unsigned int entry; -- unsigned int offset; --}; -- --struct cmap_node *cmap_next_position(const struct cmap *, -- struct cmap_position *); -- --/* Returns the first node in 'cmap', in arbitrary order, or a null pointer if -- * 'cmap' is empty. */ --static inline struct cmap_node * --cmap_first(const struct cmap *cmap) --{ -- struct cmap_position pos = { 0, 0, 0 }; -- -- return cmap_next_position(cmap, &pos); --} -- --/* Removes 'node' from 'cmap'. The caller must ensure that 'cmap' cannot -- * change concurrently (from another thread). -- * -- * 'node' must not be destroyed or modified or inserted back into 'cmap' or -- * into any other concurrent hash map while any other thread might be accessing -- * it. One correct way to do this is to free it from an RCU callback with -- * ovsrcu_postpone(). -- * -- * Returns the current number of nodes in the cmap after the removal. */ --static inline size_t --cmap_remove(struct cmap *cmap, struct cmap_node *node, uint32_t hash) --{ -- return cmap_replace(cmap, node, NULL, hash); --} -- --#endif /* cmap.h */ -Index: openvswitch-2.17.2/include/internal/cmap.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/cmap.h -@@ -0,0 +1,297 @@ -+/* -+ * Copyright (c) 2014, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef CMAP_H -+#define CMAP_H 1 -+ -+#include -+#include -+#include "openvswitch/ovs-rcu.h" -+#include "internal/util.h" -+ -+/* Concurrent hash map -+ * =================== -+ * -+ * A single-writer, multiple-reader hash table that efficiently supports -+ * duplicates. -+ * -+ * -+ * Thread-safety -+ * ============= -+ * -+ * The general rules are: -+ * -+ * - Only a single thread may safely call into cmap_insert(), -+ * cmap_remove(), or cmap_replace() at any given time. -+ * -+ * - Any number of threads may use functions and macros that search or -+ * iterate through a given cmap, even in parallel with other threads -+ * calling cmap_insert(), cmap_remove(), or cmap_replace(). -+ * -+ * There is one exception: cmap_find_protected() is only safe if no thread -+ * is currently calling cmap_insert(), cmap_remove(), or cmap_replace(). -+ * (Use ordinary cmap_find() if that is not guaranteed.) -+ * -+ * - See "Iteration" below for additional thread safety rules. -+ * -+ * Writers must use special care to ensure that any elements that they remove -+ * do not get freed or reused until readers have finished with them. This -+ * includes inserting the element back into its original cmap or a different -+ * one. One correct way to do this is to free them from an RCU callback with -+ * ovsrcu_postpone(). -+ */ -+ -+/* A concurrent hash map node, to be embedded inside the data structure being -+ * mapped. -+ * -+ * All nodes linked together on a chain have exactly the same hash value. */ -+struct cmap_node { -+ OVSRCU_TYPE(struct cmap_node *) next; /* Next node with same hash. */ -+}; -+ -+static inline struct cmap_node * -+cmap_node_next(const struct cmap_node *node) -+{ -+ return ovsrcu_get(struct cmap_node *, &node->next); -+} -+ -+static inline struct cmap_node * -+cmap_node_next_protected(const struct cmap_node *node) -+{ -+ return ovsrcu_get_protected(struct cmap_node *, &node->next); -+} -+ -+/* Concurrent hash map. */ -+struct cmap { -+ OVSRCU_TYPE(struct cmap_impl *) impl; -+}; -+ -+/* Initializer for an empty cmap. */ -+#define CMAP_INITIALIZER { \ -+ .impl = OVSRCU_INITIALIZER((struct cmap_impl *) &empty_cmap) \ -+ } -+extern OVS_ALIGNED_VAR(CACHE_LINE_SIZE) const struct cmap_impl empty_cmap; -+ -+/* Initialization. */ -+void cmap_init(struct cmap *); -+void cmap_destroy(struct cmap *); -+ -+/* Count. */ -+size_t cmap_count(const struct cmap *); -+bool cmap_is_empty(const struct cmap *); -+ -+/* Insertion and deletion. Return the current count after the operation. */ -+size_t cmap_insert(struct cmap *, struct cmap_node *, uint32_t hash); -+static inline size_t cmap_remove(struct cmap *, struct cmap_node *, -+ uint32_t hash); -+size_t cmap_replace(struct cmap *, struct cmap_node *old_node, -+ struct cmap_node *new_node, uint32_t hash); -+ -+/* Search. -+ * -+ * These macros iterate NODE over all of the nodes in CMAP that have hash value -+ * equal to HASH. MEMBER must be the name of the 'struct cmap_node' member -+ * within NODE. -+ * -+ * CMAP and HASH are evaluated only once. NODE is evaluated many times. -+ * -+ * After a normal exit of the loop (not through a "break;" statement) NODE is -+ * NULL. -+ * -+ * Thread-safety -+ * ============= -+ * -+ * CMAP_NODE_FOR_EACH will reliably visit each of the nodes starting with -+ * CMAP_NODE, even with concurrent insertions and deletions. (Of -+ * course, if nodes are being inserted or deleted, it might or might not visit -+ * the nodes actually being inserted or deleted.) -+ * -+ * CMAP_NODE_FOR_EACH_PROTECTED may only be used if the containing CMAP is -+ * guaranteed not to change during iteration. It may be only slightly faster. -+ * -+ * CMAP_FOR_EACH_WITH_HASH will reliably visit each of the nodes with the -+ * specified hash in CMAP, even with concurrent insertions and deletions. (Of -+ * course, if nodes with the given HASH are being inserted or deleted, it might -+ * or might not visit the nodes actually being inserted or deleted.) -+ * -+ * CMAP_FOR_EACH_WITH_HASH_PROTECTED may only be used if CMAP is guaranteed not -+ * to change during iteration. It may be very slightly faster. -+ */ -+#define CMAP_NODE_FOR_EACH(NODE, MEMBER, CMAP_NODE) \ -+ for (INIT_MULTIVAR(NODE, MEMBER, CMAP_NODE, struct cmap_node); \ -+ CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -+ UPDATE_MULTIVAR(NODE, cmap_node_next(ITER_VAR(NODE)))) -+#define CMAP_NODE_FOR_EACH_PROTECTED(NODE, MEMBER, CMAP_NODE) \ -+ for (INIT_MULTIVAR(NODE, MEMBER, CMAP_NODE, struct cmap_node); \ -+ CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -+ UPDATE_MULTIVAR(NODE, cmap_node_next_protected(ITER_VAR(NODE)))) -+ -+#define CMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, CMAP) \ -+ CMAP_NODE_FOR_EACH(NODE, MEMBER, cmap_find(CMAP, HASH)) -+#define CMAP_FOR_EACH_WITH_HASH_PROTECTED(NODE, MEMBER, HASH, CMAP) \ -+ CMAP_NODE_FOR_EACH_PROTECTED(NODE, MEMBER, cmap_find_protected(CMAP, HASH)) -+ -+const struct cmap_node *cmap_find(const struct cmap *, uint32_t hash); -+struct cmap_node *cmap_find_protected(const struct cmap *, uint32_t hash); -+ -+/* Find node by index or find index by hash. The 'index' of a cmap entry is a -+ * way to combine the specific bucket and the entry of the bucket into a -+ * convenient single integer value. In other words, it is the index of the -+ * entry and each entry has an unique index. It is not used internally by -+ * cmap. -+ * Currently the functions assume index will not be larger than uint32_t. In -+ * OvS table size is usually much smaller than this size.*/ -+const struct cmap_node * cmap_find_by_index(const struct cmap *, -+ uint32_t index); -+uint32_t cmap_find_index(const struct cmap *, uint32_t hash); -+ -+/* Looks up multiple 'hashes', when the corresponding bit in 'map' is 1, -+ * and sets the corresponding pointer in 'nodes', if the hash value was -+ * found from the 'cmap'. In other cases the 'nodes' values are not changed, -+ * i.e., no NULL pointers are stored there. -+ * Returns a map where a bit is set to 1 if the corresponding 'nodes' pointer -+ * was stored, 0 otherwise. -+ * Generally, the caller wants to use CMAP_NODE_FOR_EACH to verify for -+ * hash collisions. */ -+unsigned long cmap_find_batch(const struct cmap *cmap, unsigned long map, -+ uint32_t hashes[], -+ const struct cmap_node *nodes[]); -+ -+/* Iteration. -+ * -+ * -+ * Thread-safety -+ * ============= -+ * -+ * Iteration is safe even in a cmap that is changing concurrently. However: -+ * -+ * - In the presence of concurrent calls to cmap_insert(), any given -+ * iteration might skip some nodes and might visit some nodes more than -+ * once. If this is a problem, then the iterating code should lock the -+ * data structure (a rwlock can be used to allow multiple threads to -+ * iterate in parallel). -+ * -+ * - Concurrent calls to cmap_remove() don't have the same problem. (A -+ * node being deleted may be visited once or not at all. Other nodes -+ * will be visited once.) -+ * -+ * - If the cmap is changing, it is not safe to quiesce while iterating. -+ * Even if the changes are done by the same thread that's performing the -+ * iteration (Corollary: it is not safe to call cmap_remove() and quiesce -+ * in the loop body). -+ * -+ * -+ * Example -+ * ======= -+ * -+ * struct my_node { -+ * struct cmap_node cmap_node; -+ * int extra_data; -+ * }; -+ * -+ * struct cmap my_map; -+ * struct my_node *my_node; -+ * -+ * cmap_init(&my_map); -+ * ...add data... -+ * CMAP_FOR_EACH (my_node, cmap_node, &my_map) { -+ * ...operate on my_node... -+ * } -+ * -+ * CMAP_FOR_EACH is "safe" in the sense of HMAP_FOR_EACH_SAFE. That is, it is -+ * safe to free the current node before going on to the next iteration. Most -+ * of the time, though, this doesn't matter for a cmap because node -+ * deallocation has to be postponed until the next grace period. This means -+ * that this guarantee is useful only in deallocation code already executing at -+ * postponed time, when it is known that the RCU grace period has already -+ * expired. -+ */ -+ -+#define CMAP_CURSOR_FOR_EACH__(NODE, CURSOR, MEMBER) \ -+ ((CURSOR)->node \ -+ ? (INIT_CONTAINER(NODE, (CURSOR)->node, MEMBER), \ -+ cmap_cursor_advance(CURSOR), \ -+ true) \ -+ : (NODE = NULL, false)) -+ -+#define CMAP_CURSOR_FOR_EACH(NODE, MEMBER, CURSOR, CMAP) \ -+ for (*(CURSOR) = cmap_cursor_start(CMAP); \ -+ CMAP_CURSOR_FOR_EACH__(NODE, CURSOR, MEMBER); \ -+ ) -+ -+#define CMAP_CURSOR_FOR_EACH_CONTINUE(NODE, MEMBER, CURSOR) \ -+ while (CMAP_CURSOR_FOR_EACH__(NODE, CURSOR, MEMBER)) -+ -+struct cmap_cursor { -+ const struct cmap_impl *impl; -+ uint32_t bucket_idx; -+ int entry_idx; -+ struct cmap_node *node; -+}; -+ -+struct cmap_cursor cmap_cursor_start(const struct cmap *); -+void cmap_cursor_advance(struct cmap_cursor *); -+ -+/* Generate a unique name for the cursor with the __COUNTER__ macro to -+ * allow nesting of CMAP_FOR_EACH loops. */ -+#define CMAP_FOR_EACH__(NODE, MEMBER, CMAP, CURSOR_NAME) \ -+ for (struct cmap_cursor CURSOR_NAME = cmap_cursor_start(CMAP); \ -+ CMAP_CURSOR_FOR_EACH__(NODE, &CURSOR_NAME, MEMBER); \ -+ ) -+ -+#define CMAP_FOR_EACH(NODE, MEMBER, CMAP) \ -+ CMAP_FOR_EACH__(NODE, MEMBER, CMAP, \ -+ OVS_JOIN(cursor_, __COUNTER__)) -+ -+static inline struct cmap_node *cmap_first(const struct cmap *); -+ -+/* Another, less preferred, form of iteration, for use in situations where it -+ * is difficult to maintain a pointer to a cmap_node. */ -+struct cmap_position { -+ unsigned int bucket; -+ unsigned int entry; -+ unsigned int offset; -+}; -+ -+struct cmap_node *cmap_next_position(const struct cmap *, -+ struct cmap_position *); -+ -+/* Returns the first node in 'cmap', in arbitrary order, or a null pointer if -+ * 'cmap' is empty. */ -+static inline struct cmap_node * -+cmap_first(const struct cmap *cmap) -+{ -+ struct cmap_position pos = { 0, 0, 0 }; -+ -+ return cmap_next_position(cmap, &pos); -+} -+ -+/* Removes 'node' from 'cmap'. The caller must ensure that 'cmap' cannot -+ * change concurrently (from another thread). -+ * -+ * 'node' must not be destroyed or modified or inserted back into 'cmap' or -+ * into any other concurrent hash map while any other thread might be accessing -+ * it. One correct way to do this is to free it from an RCU callback with -+ * ovsrcu_postpone(). -+ * -+ * Returns the current number of nodes in the cmap after the removal. */ -+static inline size_t -+cmap_remove(struct cmap *cmap, struct cmap_node *node, uint32_t hash) -+{ -+ return cmap_replace(cmap, node, NULL, hash); -+} -+ -+#endif /* cmap.h */ -Index: openvswitch-2.17.2/lib/coverage.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/coverage.h -+++ /dev/null -@@ -1,94 +0,0 @@ --/* -- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef COVERAGE_H --#define COVERAGE_H 1 -- --/* This file implements a simple form of coverage instrumentation. Points in -- * source code that are of interest must be explicitly annotated with -- * COVERAGE_INC. The coverage counters may be logged at any time with -- * coverage_log(). -- * -- * This form of coverage instrumentation is intended to be so lightweight that -- * it can be enabled in production builds. It is obviously not a substitute -- * for traditional coverage instrumentation with e.g. "gcov", but it is still -- * a useful debugging tool. */ -- --#include "ovs-thread.h" --#include "openvswitch/compiler.h" -- --/* Makes coverage_run run every 5000 ms (5 seconds). -- * If this value is redefined, the new value must -- * divide 60000 (1 minute). */ --#define COVERAGE_RUN_INTERVAL 5000 --BUILD_ASSERT_DECL(60000 % COVERAGE_RUN_INTERVAL == 0); -- --#define COVERAGE_CLEAR_INTERVAL 1000 --BUILD_ASSERT_DECL(COVERAGE_RUN_INTERVAL % COVERAGE_CLEAR_INTERVAL == 0); -- --/* Defines the moving average array length. */ --#define MIN_AVG_LEN (60000/COVERAGE_RUN_INTERVAL) --#define HR_AVG_LEN 60 -- --/* A coverage counter. */ --struct coverage_counter { -- const char *const name; /* Textual name. */ -- unsigned int (*const count)(void); /* Gets, zeros this thread's count. */ -- unsigned long long int total; /* Total count. */ -- unsigned long long int last_total; -- /* The moving average arrays. */ -- unsigned int min[MIN_AVG_LEN]; -- unsigned int hr[HR_AVG_LEN]; --}; -- --void coverage_counter_register(struct coverage_counter*); -- --/* Defines COUNTER. There must be exactly one such definition at file scope -- * within a program. */ --#define COVERAGE_DEFINE(COUNTER) \ -- DEFINE_STATIC_PER_THREAD_DATA(unsigned int, \ -- counter_##COUNTER, 0); \ -- static unsigned int COUNTER##_count(void) \ -- { \ -- unsigned int *countp = counter_##COUNTER##_get(); \ -- unsigned int count = *countp; \ -- *countp = 0; \ -- return count; \ -- } \ -- static inline void COUNTER##_add(unsigned int n) \ -- { \ -- *counter_##COUNTER##_get() += n; \ -- } \ -- extern struct coverage_counter counter_##COUNTER; \ -- struct coverage_counter counter_##COUNTER \ -- = { #COUNTER, COUNTER##_count, 0, 0, {0}, {0} }; \ -- OVS_CONSTRUCTOR(COUNTER##_init_coverage) { \ -- coverage_counter_register(&counter_##COUNTER); \ -- } -- --/* Adds 1 to COUNTER. */ --#define COVERAGE_INC(COUNTER) COVERAGE_ADD(COUNTER, 1) -- --/* Adds AMOUNT to COUNTER. */ --#define COVERAGE_ADD(COUNTER, AMOUNT) COUNTER##_add(AMOUNT) -- --void coverage_init(void); --void coverage_log(void); --void coverage_clear(void); --void coverage_try_clear(void); --void coverage_run(void); -- --#endif /* coverage.h */ -Index: openvswitch-2.17.2/include/internal/coverage.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/coverage.h -@@ -0,0 +1,94 @@ -+/* -+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef COVERAGE_H -+#define COVERAGE_H 1 -+ -+/* This file implements a simple form of coverage instrumentation. Points in -+ * source code that are of interest must be explicitly annotated with -+ * COVERAGE_INC. The coverage counters may be logged at any time with -+ * coverage_log(). -+ * -+ * This form of coverage instrumentation is intended to be so lightweight that -+ * it can be enabled in production builds. It is obviously not a substitute -+ * for traditional coverage instrumentation with e.g. "gcov", but it is still -+ * a useful debugging tool. */ -+ -+#include "openvswitch/ovs-thread.h" -+#include "openvswitch/compiler.h" -+ -+/* Makes coverage_run run every 5000 ms (5 seconds). -+ * If this value is redefined, the new value must -+ * divide 60000 (1 minute). */ -+#define COVERAGE_RUN_INTERVAL 5000 -+BUILD_ASSERT_DECL(60000 % COVERAGE_RUN_INTERVAL == 0); -+ -+#define COVERAGE_CLEAR_INTERVAL 1000 -+BUILD_ASSERT_DECL(COVERAGE_RUN_INTERVAL % COVERAGE_CLEAR_INTERVAL == 0); -+ -+/* Defines the moving average array length. */ -+#define MIN_AVG_LEN (60000/COVERAGE_RUN_INTERVAL) -+#define HR_AVG_LEN 60 -+ -+/* A coverage counter. */ -+struct coverage_counter { -+ const char *const name; /* Textual name. */ -+ unsigned int (*const count)(void); /* Gets, zeros this thread's count. */ -+ unsigned long long int total; /* Total count. */ -+ unsigned long long int last_total; -+ /* The moving average arrays. */ -+ unsigned int min[MIN_AVG_LEN]; -+ unsigned int hr[HR_AVG_LEN]; -+}; -+ -+void coverage_counter_register(struct coverage_counter*); -+ -+/* Defines COUNTER. There must be exactly one such definition at file scope -+ * within a program. */ -+#define COVERAGE_DEFINE(COUNTER) \ -+ DEFINE_STATIC_PER_THREAD_DATA(unsigned int, \ -+ counter_##COUNTER, 0); \ -+ static unsigned int COUNTER##_count(void) \ -+ { \ -+ unsigned int *countp = counter_##COUNTER##_get(); \ -+ unsigned int count = *countp; \ -+ *countp = 0; \ -+ return count; \ -+ } \ -+ static inline void COUNTER##_add(unsigned int n) \ -+ { \ -+ *counter_##COUNTER##_get() += n; \ -+ } \ -+ extern struct coverage_counter counter_##COUNTER; \ -+ struct coverage_counter counter_##COUNTER \ -+ = { #COUNTER, COUNTER##_count, 0, 0, {0}, {0} }; \ -+ OVS_CONSTRUCTOR(COUNTER##_init_coverage) { \ -+ coverage_counter_register(&counter_##COUNTER); \ -+ } -+ -+/* Adds 1 to COUNTER. */ -+#define COVERAGE_INC(COUNTER) COVERAGE_ADD(COUNTER, 1) -+ -+/* Adds AMOUNT to COUNTER. */ -+#define COVERAGE_ADD(COUNTER, AMOUNT) COUNTER##_add(AMOUNT) -+ -+void coverage_init(void); -+void coverage_log(void); -+void coverage_clear(void); -+void coverage_try_clear(void); -+void coverage_run(void); -+ -+#endif /* coverage.h */ -Index: openvswitch-2.17.2/lib/dhcp.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dhcp.h -+++ /dev/null -@@ -1,65 +0,0 @@ --/* -- * Copyright (c) 2008, 2011 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef DHCP_H --#define DHCP_H 1 -- --#include --#include "packets.h" --#include "util.h" -- --/* Ports used by DHCP. */ --#define DHCP_SERVER_PORT 67 /* Port used by DHCP server. */ --#define DHCP_CLIENT_PORT 68 /* Port used by DHCP client. */ -- --#define DHCP_MAGIC_COOKIE 0x63825363 -- --#define DHCP_HEADER_LEN 236 --OVS_PACKED( --struct dhcp_header { -- uint8_t op; /* DHCP_BOOTREQUEST or DHCP_BOOTREPLY. */ -- uint8_t htype; /* ARP_HRD_ETHERNET (typically). */ -- uint8_t hlen; /* ETH_ADDR_LEN (typically). */ -- uint8_t hops; /* Hop count; set to 0 by client. */ -- ovs_be32 xid; /* Transaction ID. */ -- ovs_be16 secs; /* Since client started address acquisition. */ -- ovs_be16 flags; /* DHCP_FLAGS_*. */ -- ovs_be32 ciaddr; /* Client IP, if it has a lease for one. */ -- ovs_be32 yiaddr; /* Client ("your") IP address. */ -- ovs_be32 siaddr; /* Next server IP address. */ -- ovs_be32 giaddr; /* Relay agent IP address. */ -- uint8_t chaddr[16]; /* Client hardware address. */ -- char sname[64]; /* Optional server host name. */ -- char file[128]; /* Boot file name. */ -- /* Followed by variable-length options field. */ --}); --BUILD_ASSERT_DECL(DHCP_HEADER_LEN == sizeof(struct dhcp_header)); -- --#define DHCP_OP_REQUEST 1 --#define DHCP_OP_REPLY 2 -- --#define DHCP_MSG_DISCOVER 1 --#define DHCP_MSG_OFFER 2 --#define DHCP_MSG_REQUEST 3 --#define DHCP_MSG_ACK 5 --#define DHCP_MSG_NAK 6 -- --#define DHCP_OPT_PAD 0 --#define DHCP_OPT_REQ_IP 50 --#define DHCP_OPT_MSG_TYPE 53 --#define DHCP_OPT_END 255 -- --#endif /* dhcp.h */ -Index: openvswitch-2.17.2/include/internal/dhcp.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/dhcp.h -@@ -0,0 +1,65 @@ -+/* -+ * Copyright (c) 2008, 2011 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef DHCP_H -+#define DHCP_H 1 -+ -+#include -+#include "internal/packets.h" -+#include "internal/util.h" -+ -+/* Ports used by DHCP. */ -+#define DHCP_SERVER_PORT 67 /* Port used by DHCP server. */ -+#define DHCP_CLIENT_PORT 68 /* Port used by DHCP client. */ -+ -+#define DHCP_MAGIC_COOKIE 0x63825363 -+ -+#define DHCP_HEADER_LEN 236 -+OVS_PACKED( -+struct dhcp_header { -+ uint8_t op; /* DHCP_BOOTREQUEST or DHCP_BOOTREPLY. */ -+ uint8_t htype; /* ARP_HRD_ETHERNET (typically). */ -+ uint8_t hlen; /* ETH_ADDR_LEN (typically). */ -+ uint8_t hops; /* Hop count; set to 0 by client. */ -+ ovs_be32 xid; /* Transaction ID. */ -+ ovs_be16 secs; /* Since client started address acquisition. */ -+ ovs_be16 flags; /* DHCP_FLAGS_*. */ -+ ovs_be32 ciaddr; /* Client IP, if it has a lease for one. */ -+ ovs_be32 yiaddr; /* Client ("your") IP address. */ -+ ovs_be32 siaddr; /* Next server IP address. */ -+ ovs_be32 giaddr; /* Relay agent IP address. */ -+ uint8_t chaddr[16]; /* Client hardware address. */ -+ char sname[64]; /* Optional server host name. */ -+ char file[128]; /* Boot file name. */ -+ /* Followed by variable-length options field. */ -+}); -+BUILD_ASSERT_DECL(DHCP_HEADER_LEN == sizeof(struct dhcp_header)); -+ -+#define DHCP_OP_REQUEST 1 -+#define DHCP_OP_REPLY 2 -+ -+#define DHCP_MSG_DISCOVER 1 -+#define DHCP_MSG_OFFER 2 -+#define DHCP_MSG_REQUEST 3 -+#define DHCP_MSG_ACK 5 -+#define DHCP_MSG_NAK 6 -+ -+#define DHCP_OPT_PAD 0 -+#define DHCP_OPT_REQ_IP 50 -+#define DHCP_OPT_MSG_TYPE 53 -+#define DHCP_OPT_END 255 -+ -+#endif /* dhcp.h */ -Index: openvswitch-2.17.2/lib/dp-packet.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dp-packet.h -+++ /dev/null -@@ -1,1092 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef DPBUF_H --#define DPBUF_H 1 -- --#include --#include -- --#ifdef DPDK_NETDEV --#include --#include --#endif -- --#include "netdev-afxdp.h" --#include "netdev-dpdk.h" --#include "openvswitch/list.h" --#include "packets.h" --#include "util.h" --#include "flow.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --enum OVS_PACKED_ENUM dp_packet_source { -- DPBUF_MALLOC, /* Obtained via malloc(). */ -- DPBUF_STACK, /* Un-movable stack space or static buffer. */ -- DPBUF_STUB, /* Starts on stack, may expand into heap. */ -- DPBUF_DPDK, /* buffer data is from DPDK allocated memory. -- * ref to dp_packet_init_dpdk() in dp-packet.c. -- */ -- DPBUF_AFXDP, /* Buffer data from XDP frame. */ --}; -- --#define DP_PACKET_CONTEXT_SIZE 64 -- --#ifdef DPDK_NETDEV --#define DEF_OL_FLAG(NAME, DPDK_DEF, GENERIC_DEF) NAME = DPDK_DEF --#else --#define DEF_OL_FLAG(NAME, DPDK_DEF, GENERIC_DEF) NAME = GENERIC_DEF --#endif -- --/* Bit masks for the 'ol_flags' member of the 'dp_packet' structure. */ --enum dp_packet_offload_mask { -- /* Value 0 is not used. */ -- /* Is the 'rss_hash' valid? */ -- DEF_OL_FLAG(DP_PACKET_OL_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, 0x1), -- /* Is the 'flow_mark' valid? */ -- DEF_OL_FLAG(DP_PACKET_OL_FLOW_MARK, RTE_MBUF_F_RX_FDIR_ID, 0x2), -- /* Bad L4 checksum in the packet. */ -- DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_BAD, RTE_MBUF_F_RX_L4_CKSUM_BAD, 0x4), -- /* Bad IP checksum in the packet. */ -- DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_BAD, RTE_MBUF_F_RX_IP_CKSUM_BAD, 0x8), -- /* Valid L4 checksum in the packet. */ -- DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_GOOD, -- 0x10), -- /* Valid IP checksum in the packet. */ -- DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_GOOD, -- 0x20), -- /* TCP Segmentation Offload. */ -- DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_SEG, RTE_MBUF_F_TX_TCP_SEG, 0x40), -- /* Offloaded packet is IPv4. */ -- DEF_OL_FLAG(DP_PACKET_OL_TX_IPV4, RTE_MBUF_F_TX_IPV4, 0x80), -- /* Offloaded packet is IPv6. */ -- DEF_OL_FLAG(DP_PACKET_OL_TX_IPV6, RTE_MBUF_F_TX_IPV6, 0x100), -- /* Offload TCP checksum. */ -- DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_CKSUM, RTE_MBUF_F_TX_TCP_CKSUM, 0x200), -- /* Offload UDP checksum. */ -- DEF_OL_FLAG(DP_PACKET_OL_TX_UDP_CKSUM, RTE_MBUF_F_TX_UDP_CKSUM, 0x400), -- /* Offload SCTP checksum. */ -- DEF_OL_FLAG(DP_PACKET_OL_TX_SCTP_CKSUM, RTE_MBUF_F_TX_SCTP_CKSUM, 0x800), -- /* Adding new field requires adding to DP_PACKET_OL_SUPPORTED_MASK. */ --}; -- --#define DP_PACKET_OL_SUPPORTED_MASK (DP_PACKET_OL_RSS_HASH | \ -- DP_PACKET_OL_FLOW_MARK | \ -- DP_PACKET_OL_RX_L4_CKSUM_BAD | \ -- DP_PACKET_OL_RX_IP_CKSUM_BAD | \ -- DP_PACKET_OL_RX_L4_CKSUM_GOOD | \ -- DP_PACKET_OL_RX_IP_CKSUM_GOOD | \ -- DP_PACKET_OL_TX_TCP_SEG | \ -- DP_PACKET_OL_TX_IPV4 | \ -- DP_PACKET_OL_TX_IPV6 | \ -- DP_PACKET_OL_TX_TCP_CKSUM | \ -- DP_PACKET_OL_TX_UDP_CKSUM | \ -- DP_PACKET_OL_TX_SCTP_CKSUM) -- --#define DP_PACKET_OL_TX_L4_MASK (DP_PACKET_OL_TX_TCP_CKSUM | \ -- DP_PACKET_OL_TX_UDP_CKSUM | \ -- DP_PACKET_OL_TX_SCTP_CKSUM) --#define DP_PACKET_OL_RX_IP_CKSUM_MASK (DP_PACKET_OL_RX_IP_CKSUM_GOOD | \ -- DP_PACKET_OL_RX_IP_CKSUM_BAD) --#define DP_PACKET_OL_RX_L4_CKSUM_MASK (DP_PACKET_OL_RX_L4_CKSUM_GOOD | \ -- DP_PACKET_OL_RX_L4_CKSUM_BAD) -- --/* Buffer for holding packet data. A dp_packet is automatically reallocated -- * as necessary if it grows too large for the available memory. -- * By default the packet type is set to Ethernet (PT_ETH). -- */ --struct dp_packet { --#ifdef DPDK_NETDEV -- struct rte_mbuf mbuf; /* DPDK mbuf */ --#else -- void *base_; /* First byte of allocated space. */ -- uint16_t allocated_; /* Number of bytes allocated. */ -- uint16_t data_ofs; /* First byte actually in use. */ -- uint32_t size_; /* Number of bytes in use. */ -- uint32_t ol_flags; /* Offloading flags. */ -- uint32_t rss_hash; /* Packet hash. */ -- uint32_t flow_mark; /* Packet flow mark. */ --#endif -- enum dp_packet_source source; /* Source of memory allocated as 'base'. */ -- -- /* All the following elements of this struct are copied in a single call -- * of memcpy in dp_packet_clone_with_headroom. */ -- uint16_t l2_pad_size; /* Detected l2 padding size. -- * Padding is non-pullable. */ -- uint16_t l2_5_ofs; /* MPLS label stack offset, or UINT16_MAX */ -- uint16_t l3_ofs; /* Network-level header offset, -- * or UINT16_MAX. */ -- uint16_t l4_ofs; /* Transport-level header offset, -- or UINT16_MAX. */ -- uint32_t cutlen; /* length in bytes to cut from the end. */ -- ovs_be32 packet_type; /* Packet type as defined in OpenFlow */ -- union { -- struct pkt_metadata md; -- uint64_t data[DP_PACKET_CONTEXT_SIZE / 8]; -- }; --}; -- --#if HAVE_AF_XDP --struct dp_packet_afxdp { -- struct umem_pool *mpool; -- struct dp_packet packet; --}; --#endif -- --static inline void *dp_packet_data(const struct dp_packet *); --static inline void dp_packet_set_data(struct dp_packet *, void *); --static inline void *dp_packet_base(const struct dp_packet *); --static inline void dp_packet_set_base(struct dp_packet *, void *); -- --static inline uint32_t dp_packet_size(const struct dp_packet *); --static inline void dp_packet_set_size(struct dp_packet *, uint32_t); -- --static inline uint16_t dp_packet_get_allocated(const struct dp_packet *); --static inline void dp_packet_set_allocated(struct dp_packet *, uint16_t); -- --void *dp_packet_resize_l2(struct dp_packet *, int increment); --void *dp_packet_resize_l2_5(struct dp_packet *, int increment); --static inline void *dp_packet_eth(const struct dp_packet *); --static inline void dp_packet_reset_offsets(struct dp_packet *); --static inline uint16_t dp_packet_l2_pad_size(const struct dp_packet *); --static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint16_t); --static inline void *dp_packet_l2_5(const struct dp_packet *); --static inline void dp_packet_set_l2_5(struct dp_packet *, void *); --static inline void *dp_packet_l3(const struct dp_packet *); --static inline void dp_packet_set_l3(struct dp_packet *, void *); --static inline void *dp_packet_l4(const struct dp_packet *); --static inline void dp_packet_set_l4(struct dp_packet *, void *); --static inline size_t dp_packet_l4_size(const struct dp_packet *); --static inline const void *dp_packet_get_tcp_payload(const struct dp_packet *); --static inline const void *dp_packet_get_udp_payload(const struct dp_packet *); --static inline const void *dp_packet_get_sctp_payload(const struct dp_packet *); --static inline const void *dp_packet_get_icmp_payload(const struct dp_packet *); --static inline const void *dp_packet_get_nd_payload(const struct dp_packet *); -- --void dp_packet_use(struct dp_packet *, void *, size_t); --void dp_packet_use_stub(struct dp_packet *, void *, size_t); --void dp_packet_use_const(struct dp_packet *, const void *, size_t); --#if HAVE_AF_XDP --void dp_packet_use_afxdp(struct dp_packet *, void *, size_t, size_t); --#endif --void dp_packet_init_dpdk(struct dp_packet *); -- --void dp_packet_init(struct dp_packet *, size_t); --void dp_packet_uninit(struct dp_packet *); -- --struct dp_packet *dp_packet_new(size_t); --struct dp_packet *dp_packet_new_with_headroom(size_t, size_t headroom); --struct dp_packet *dp_packet_clone(const struct dp_packet *); --struct dp_packet *dp_packet_clone_with_headroom(const struct dp_packet *, -- size_t headroom); --struct dp_packet *dp_packet_clone_data(const void *, size_t); --struct dp_packet *dp_packet_clone_data_with_headroom(const void *, size_t, -- size_t headroom); --void dp_packet_resize(struct dp_packet *b, size_t new_headroom, -- size_t new_tailroom); --static inline void dp_packet_delete(struct dp_packet *); --static inline void dp_packet_swap(struct dp_packet *, struct dp_packet *); -- --static inline void *dp_packet_at(const struct dp_packet *, size_t offset, -- size_t size); --static inline void *dp_packet_at_assert(const struct dp_packet *, -- size_t offset, size_t size); --static inline void *dp_packet_tail(const struct dp_packet *); --static inline void *dp_packet_end(const struct dp_packet *); -- --void *dp_packet_put_uninit(struct dp_packet *, size_t); --void *dp_packet_put_zeros(struct dp_packet *, size_t); --void *dp_packet_put(struct dp_packet *, const void *, size_t); --char *dp_packet_put_hex(struct dp_packet *, const char *s, size_t *n); --void dp_packet_reserve(struct dp_packet *, size_t); --void dp_packet_reserve_with_tailroom(struct dp_packet *, size_t headroom, -- size_t tailroom); --void *dp_packet_push_uninit(struct dp_packet *, size_t); --void *dp_packet_push_zeros(struct dp_packet *, size_t); --void *dp_packet_push(struct dp_packet *, const void *, size_t); -- --static inline size_t dp_packet_headroom(const struct dp_packet *); --static inline size_t dp_packet_tailroom(const struct dp_packet *); --void dp_packet_prealloc_headroom(struct dp_packet *, size_t); --void dp_packet_prealloc_tailroom(struct dp_packet *, size_t); --void dp_packet_shift(struct dp_packet *, int); -- --static inline void dp_packet_clear(struct dp_packet *); --static inline void *dp_packet_pull(struct dp_packet *, size_t); --static inline void *dp_packet_try_pull(struct dp_packet *, size_t); -- --void *dp_packet_steal_data(struct dp_packet *); -- --static inline bool dp_packet_equal(const struct dp_packet *, -- const struct dp_packet *); -- -- --/* Frees memory that 'b' points to, as well as 'b' itself. */ --static inline void --dp_packet_delete(struct dp_packet *b) --{ -- if (b) { -- if (b->source == DPBUF_DPDK) { -- /* If this dp_packet was allocated by DPDK it must have been -- * created as a dp_packet */ -- free_dpdk_buf((struct dp_packet*) b); -- return; -- } -- -- if (b->source == DPBUF_AFXDP) { -- free_afxdp_buf(b); -- return; -- } -- -- dp_packet_uninit(b); -- free(b); -- } --} -- --/* Swaps content of two packets. */ --static inline void --dp_packet_swap(struct dp_packet *a, struct dp_packet *b) --{ -- ovs_assert(a->source == DPBUF_MALLOC || a->source == DPBUF_STUB); -- ovs_assert(b->source == DPBUF_MALLOC || b->source == DPBUF_STUB); -- struct dp_packet c = *a; -- -- *a = *b; -- *b = c; --} -- --/* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to -- * byte 'offset'. Otherwise, returns a null pointer. */ --static inline void * --dp_packet_at(const struct dp_packet *b, size_t offset, size_t size) --{ -- return offset + size <= dp_packet_size(b) -- ? (char *) dp_packet_data(b) + offset -- : NULL; --} -- --/* Returns a pointer to byte 'offset' in 'b', which must contain at least -- * 'offset + size' bytes of data. */ --static inline void * --dp_packet_at_assert(const struct dp_packet *b, size_t offset, size_t size) --{ -- ovs_assert(offset + size <= dp_packet_size(b)); -- return ((char *) dp_packet_data(b)) + offset; --} -- --/* Returns a pointer to byte following the last byte of data in use in 'b'. */ --static inline void * --dp_packet_tail(const struct dp_packet *b) --{ -- return (char *) dp_packet_data(b) + dp_packet_size(b); --} -- --/* Returns a pointer to byte following the last byte allocated for use (but -- * not necessarily in use) in 'b'. */ --static inline void * --dp_packet_end(const struct dp_packet *b) --{ -- return (char *) dp_packet_base(b) + dp_packet_get_allocated(b); --} -- --/* Returns the number of bytes of headroom in 'b', that is, the number of bytes -- * of unused space in dp_packet 'b' before the data that is in use. (Most -- * commonly, the data in a dp_packet is at its beginning, and thus the -- * dp_packet's headroom is 0.) */ --static inline size_t --dp_packet_headroom(const struct dp_packet *b) --{ -- return (char *) dp_packet_data(b) - (char *) dp_packet_base(b); --} -- --/* Returns the number of bytes that may be appended to the tail end of -- * dp_packet 'b' before the dp_packet must be reallocated. */ --static inline size_t --dp_packet_tailroom(const struct dp_packet *b) --{ -- return (char *) dp_packet_end(b) - (char *) dp_packet_tail(b); --} -- --/* Clears any data from 'b'. */ --static inline void --dp_packet_clear(struct dp_packet *b) --{ -- dp_packet_set_data(b, dp_packet_base(b)); -- dp_packet_set_size(b, 0); --} -- --/* Removes 'size' bytes from the head end of 'b', which must contain at least -- * 'size' bytes of data. Returns the first byte of data removed. */ --static inline void * --dp_packet_pull(struct dp_packet *b, size_t size) --{ -- void *data = dp_packet_data(b); -- ovs_assert(dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size); -- dp_packet_set_data(b, (char *) dp_packet_data(b) + size); -- dp_packet_set_size(b, dp_packet_size(b) - size); -- return data; --} -- --/* If 'b' has at least 'size' bytes of data, removes that many bytes from the -- * head end of 'b' and returns the first byte removed. Otherwise, returns a -- * null pointer without modifying 'b'. */ --static inline void * --dp_packet_try_pull(struct dp_packet *b, size_t size) --{ -- return dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size -- ? dp_packet_pull(b, size) : NULL; --} -- --static inline bool --dp_packet_equal(const struct dp_packet *a, const struct dp_packet *b) --{ -- return dp_packet_size(a) == dp_packet_size(b) && -- !memcmp(dp_packet_data(a), dp_packet_data(b), dp_packet_size(a)); --} -- --static inline bool --dp_packet_is_eth(const struct dp_packet *b) --{ -- return b->packet_type == htonl(PT_ETH); --} -- --/* Get the start of the Ethernet frame. 'l3_ofs' marks the end of the l2 -- * headers, so return NULL if it is not set. */ --static inline void * --dp_packet_eth(const struct dp_packet *b) --{ -- return (dp_packet_is_eth(b) && b->l3_ofs != UINT16_MAX) -- ? dp_packet_data(b) : NULL; --} -- --/* Resets all layer offsets. 'l3' offset must be set before 'l2' can be -- * retrieved. */ --static inline void --dp_packet_reset_offsets(struct dp_packet *b) --{ -- b->l2_pad_size = 0; -- b->l2_5_ofs = UINT16_MAX; -- b->l3_ofs = UINT16_MAX; -- b->l4_ofs = UINT16_MAX; --} -- --static inline uint16_t --dp_packet_l2_pad_size(const struct dp_packet *b) --{ -- return b->l2_pad_size; --} -- --static inline void --dp_packet_set_l2_pad_size(struct dp_packet *b, uint16_t pad_size) --{ -- ovs_assert(pad_size <= dp_packet_size(b)); -- b->l2_pad_size = pad_size; --} -- --static inline void * --dp_packet_l2_5(const struct dp_packet *b) --{ -- return b->l2_5_ofs != UINT16_MAX -- ? (char *) dp_packet_data(b) + b->l2_5_ofs -- : NULL; --} -- --static inline void --dp_packet_set_l2_5(struct dp_packet *b, void *l2_5) --{ -- b->l2_5_ofs = l2_5 -- ? (char *) l2_5 - (char *) dp_packet_data(b) -- : UINT16_MAX; --} -- --static inline void * --dp_packet_l3(const struct dp_packet *b) --{ -- return b->l3_ofs != UINT16_MAX -- ? (char *) dp_packet_data(b) + b->l3_ofs -- : NULL; --} -- --static inline void --dp_packet_set_l3(struct dp_packet *b, void *l3) --{ -- b->l3_ofs = l3 ? (char *) l3 - (char *) dp_packet_data(b) : UINT16_MAX; --} -- --static inline void * --dp_packet_l4(const struct dp_packet *b) --{ -- return b->l4_ofs != UINT16_MAX -- ? (char *) dp_packet_data(b) + b->l4_ofs -- : NULL; --} -- --static inline void --dp_packet_set_l4(struct dp_packet *b, void *l4) --{ -- b->l4_ofs = l4 ? (char *) l4 - (char *) dp_packet_data(b) : UINT16_MAX; --} -- --/* Returns the size of the packet from the beginning of the L3 header to the -- * end of the L3 payload. Hence L2 padding is not included. */ --static inline size_t --dp_packet_l3_size(const struct dp_packet *b) --{ -- return OVS_LIKELY(b->l3_ofs != UINT16_MAX) -- ? (const char *)dp_packet_tail(b) - (const char *)dp_packet_l3(b) -- - dp_packet_l2_pad_size(b) -- : 0; --} -- --/* Returns the size of the packet from the beginning of the L4 header to the -- * end of the L4 payload. Hence L2 padding is not included. */ --static inline size_t --dp_packet_l4_size(const struct dp_packet *b) --{ -- return OVS_LIKELY(b->l4_ofs != UINT16_MAX) -- ? (const char *)dp_packet_tail(b) - (const char *)dp_packet_l4(b) -- - dp_packet_l2_pad_size(b) -- : 0; --} -- --static inline const void * --dp_packet_get_tcp_payload(const struct dp_packet *b) --{ -- size_t l4_size = dp_packet_l4_size(b); -- -- if (OVS_LIKELY(l4_size >= TCP_HEADER_LEN)) { -- struct tcp_header *tcp = dp_packet_l4(b); -- int tcp_len = TCP_OFFSET(tcp->tcp_ctl) * 4; -- -- if (OVS_LIKELY(tcp_len >= TCP_HEADER_LEN && tcp_len <= l4_size)) { -- return (const char *)tcp + tcp_len; -- } -- } -- return NULL; --} -- --static inline uint32_t --dp_packet_get_tcp_payload_length(const struct dp_packet *pkt) --{ -- const char *tcp_payload = dp_packet_get_tcp_payload(pkt); -- if (tcp_payload) { -- return ((char *) dp_packet_tail(pkt) - dp_packet_l2_pad_size(pkt) -- - tcp_payload); -- } else { -- return 0; -- } --} -- --static inline const void * --dp_packet_get_udp_payload(const struct dp_packet *b) --{ -- return OVS_LIKELY(dp_packet_l4_size(b) >= UDP_HEADER_LEN) -- ? (const char *)dp_packet_l4(b) + UDP_HEADER_LEN : NULL; --} -- --static inline const void * --dp_packet_get_sctp_payload(const struct dp_packet *b) --{ -- return OVS_LIKELY(dp_packet_l4_size(b) >= SCTP_HEADER_LEN) -- ? (const char *)dp_packet_l4(b) + SCTP_HEADER_LEN : NULL; --} -- --static inline const void * --dp_packet_get_icmp_payload(const struct dp_packet *b) --{ -- return OVS_LIKELY(dp_packet_l4_size(b) >= ICMP_HEADER_LEN) -- ? (const char *)dp_packet_l4(b) + ICMP_HEADER_LEN : NULL; --} -- --static inline const void * --dp_packet_get_nd_payload(const struct dp_packet *b) --{ -- return OVS_LIKELY(dp_packet_l4_size(b) >= ND_MSG_LEN) -- ? (const char *)dp_packet_l4(b) + ND_MSG_LEN : NULL; --} -- --#ifdef DPDK_NETDEV --static inline uint64_t * --dp_packet_ol_flags_ptr(const struct dp_packet *b) --{ -- return CONST_CAST(uint64_t *, &b->mbuf.ol_flags); --} -- --static inline uint32_t * --dp_packet_rss_ptr(const struct dp_packet *b) --{ -- return CONST_CAST(uint32_t *, &b->mbuf.hash.rss); --} -- --static inline uint32_t * --dp_packet_flow_mark_ptr(const struct dp_packet *b) --{ -- return CONST_CAST(uint32_t *, &b->mbuf.hash.fdir.hi); --} -- --#else --static inline uint32_t * --dp_packet_ol_flags_ptr(const struct dp_packet *b) --{ -- return CONST_CAST(uint32_t *, &b->ol_flags); --} -- --static inline uint32_t * --dp_packet_rss_ptr(const struct dp_packet *b) --{ -- return CONST_CAST(uint32_t *, &b->rss_hash); --} -- --static inline uint32_t * --dp_packet_flow_mark_ptr(const struct dp_packet *b) --{ -- return CONST_CAST(uint32_t *, &b->flow_mark); --} --#endif -- --#ifdef DPDK_NETDEV --BUILD_ASSERT_DECL(offsetof(struct dp_packet, mbuf) == 0); -- --static inline void --dp_packet_init_specific(struct dp_packet *p) --{ -- /* This initialization is needed for packets that do not come from DPDK -- * interfaces, when vswitchd is built with --with-dpdk. */ -- p->mbuf.ol_flags = p->mbuf.tx_offload = p->mbuf.packet_type = 0; -- p->mbuf.nb_segs = 1; -- p->mbuf.next = NULL; --} -- --static inline void * --dp_packet_base(const struct dp_packet *b) --{ -- return b->mbuf.buf_addr; --} -- --static inline void --dp_packet_set_base(struct dp_packet *b, void *d) --{ -- b->mbuf.buf_addr = d; --} -- --static inline uint32_t --dp_packet_size(const struct dp_packet *b) --{ -- return b->mbuf.pkt_len; --} -- --static inline void --dp_packet_set_size(struct dp_packet *b, uint32_t v) --{ -- /* netdev-dpdk does not currently support segmentation; consequently, for -- * all intents and purposes, 'data_len' (16 bit) and 'pkt_len' (32 bit) may -- * be used interchangably. -- * -- * On the datapath, it is expected that the size of packets -- * (and thus 'v') will always be <= UINT16_MAX; this means that there is no -- * loss of accuracy in assigning 'v' to 'data_len'. -- */ -- b->mbuf.data_len = (uint16_t)v; /* Current seg length. */ -- b->mbuf.pkt_len = v; /* Total length of all segments linked to -- * this segment. */ --} -- --static inline uint16_t --__packet_data(const struct dp_packet *b) --{ -- return b->mbuf.data_off; --} -- --static inline void --__packet_set_data(struct dp_packet *b, uint16_t v) --{ -- b->mbuf.data_off = v; --} -- --static inline uint16_t --dp_packet_get_allocated(const struct dp_packet *b) --{ -- return b->mbuf.buf_len; --} -- --static inline void --dp_packet_set_allocated(struct dp_packet *b, uint16_t s) --{ -- b->mbuf.buf_len = s; --} -- --#else /* DPDK_NETDEV */ -- --static inline void --dp_packet_init_specific(struct dp_packet *p OVS_UNUSED) --{ -- /* There are no implementation-specific fields for initialization. */ --} -- --static inline void * --dp_packet_base(const struct dp_packet *b) --{ -- return b->base_; --} -- --static inline void --dp_packet_set_base(struct dp_packet *b, void *d) --{ -- b->base_ = d; --} -- --static inline uint32_t --dp_packet_size(const struct dp_packet *b) --{ -- return b->size_; --} -- --static inline void --dp_packet_set_size(struct dp_packet *b, uint32_t v) --{ -- b->size_ = v; --} -- --static inline uint16_t --__packet_data(const struct dp_packet *b) --{ -- return b->data_ofs; --} -- --static inline void --__packet_set_data(struct dp_packet *b, uint16_t v) --{ -- b->data_ofs = v; --} -- --static inline uint16_t --dp_packet_get_allocated(const struct dp_packet *b) --{ -- return b->allocated_; --} -- --static inline void --dp_packet_set_allocated(struct dp_packet *b, uint16_t s) --{ -- b->allocated_ = s; --} -- --#endif /* DPDK_NETDEV */ -- --static inline void --dp_packet_reset_cutlen(struct dp_packet *b) --{ -- b->cutlen = 0; --} -- --static inline uint32_t --dp_packet_set_cutlen(struct dp_packet *b, uint32_t max_len) --{ -- if (max_len < ETH_HEADER_LEN) { -- max_len = ETH_HEADER_LEN; -- } -- -- if (max_len >= dp_packet_size(b)) { -- b->cutlen = 0; -- } else { -- b->cutlen = dp_packet_size(b) - max_len; -- } -- return b->cutlen; --} -- --static inline uint32_t --dp_packet_get_cutlen(const struct dp_packet *b) --{ -- /* Always in valid range if user uses dp_packet_set_cutlen. */ -- return b->cutlen; --} -- --static inline uint32_t --dp_packet_get_send_len(const struct dp_packet *b) --{ -- return dp_packet_size(b) - dp_packet_get_cutlen(b); --} -- --static inline void * --dp_packet_data(const struct dp_packet *b) --{ -- return __packet_data(b) != UINT16_MAX -- ? (char *) dp_packet_base(b) + __packet_data(b) : NULL; --} -- --static inline void --dp_packet_set_data(struct dp_packet *b, void *data) --{ -- if (data) { -- __packet_set_data(b, (char *) data - (char *) dp_packet_base(b)); -- } else { -- __packet_set_data(b, UINT16_MAX); -- } --} -- --static inline void --dp_packet_reset_packet(struct dp_packet *b, int off) --{ -- dp_packet_set_size(b, dp_packet_size(b) - off); -- dp_packet_set_data(b, ((unsigned char *) dp_packet_data(b) + off)); -- dp_packet_reset_offsets(b); --} -- --enum { NETDEV_MAX_BURST = 32 }; /* Maximum number packets in a batch. */ -- --struct dp_packet_batch { -- size_t count; -- bool trunc; /* true if the batch needs truncate. */ -- struct dp_packet *packets[NETDEV_MAX_BURST]; --}; -- --static inline void --dp_packet_batch_init(struct dp_packet_batch *batch) --{ -- batch->count = 0; -- batch->trunc = false; --} -- --static inline void --dp_packet_batch_add__(struct dp_packet_batch *batch, -- struct dp_packet *packet, size_t limit) --{ -- if (batch->count < limit) { -- batch->packets[batch->count++] = packet; -- } else { -- dp_packet_delete(packet); -- } --} -- --/* When the batch is full, 'packet' will be dropped and freed. */ --static inline void --dp_packet_batch_add(struct dp_packet_batch *batch, struct dp_packet *packet) --{ -- dp_packet_batch_add__(batch, packet, NETDEV_MAX_BURST); --} -- --static inline size_t --dp_packet_batch_size(const struct dp_packet_batch *batch) --{ -- return batch->count; --} -- --/* Clear 'batch' for refill. Use dp_packet_batch_refill() to add -- * packets back into the 'batch'. */ --static inline void --dp_packet_batch_refill_init(struct dp_packet_batch *batch) --{ -- batch->count = 0; --}; -- --static inline void --dp_packet_batch_refill(struct dp_packet_batch *batch, -- struct dp_packet *packet, size_t idx) --{ -- dp_packet_batch_add__(batch, packet, MIN(NETDEV_MAX_BURST, idx + 1)); --} -- --static inline void --dp_packet_batch_init_packet(struct dp_packet_batch *batch, struct dp_packet *p) --{ -- dp_packet_batch_init(batch); -- batch->count = 1; -- batch->packets[0] = p; --} -- --static inline bool --dp_packet_batch_is_empty(const struct dp_packet_batch *batch) --{ -- return !dp_packet_batch_size(batch); --} -- --static inline bool --dp_packet_batch_is_full(const struct dp_packet_batch *batch) --{ -- return dp_packet_batch_size(batch) == NETDEV_MAX_BURST; --} -- --#define DP_PACKET_BATCH_FOR_EACH(IDX, PACKET, BATCH) \ -- for (size_t IDX = 0; IDX < dp_packet_batch_size(BATCH); IDX++) \ -- if (PACKET = BATCH->packets[IDX], true) -- --/* Use this macro for cases where some packets in the 'BATCH' may be -- * dropped after going through each packet in the 'BATCH'. -- * -- * For packets to stay in the 'BATCH', they need to be refilled back -- * into the 'BATCH' by calling dp_packet_batch_refill(). Caller owns -- * the packets that are not refilled. -- * -- * Caller needs to supply 'SIZE', that stores the current number of -- * packets in 'BATCH'. It is best to declare this variable with -- * the 'const' modifier since it should not be modified by -- * the iterator. */ --#define DP_PACKET_BATCH_REFILL_FOR_EACH(IDX, SIZE, PACKET, BATCH) \ -- for (dp_packet_batch_refill_init(BATCH), IDX=0; IDX < SIZE; IDX++) \ -- if (PACKET = BATCH->packets[IDX], true) -- --static inline void --dp_packet_batch_clone(struct dp_packet_batch *dst, -- struct dp_packet_batch *src) --{ -- struct dp_packet *packet; -- -- dp_packet_batch_init(dst); -- DP_PACKET_BATCH_FOR_EACH (i, packet, src) { -- if (i + 1 < dp_packet_batch_size(src)) { -- OVS_PREFETCH(src->packets[i + 1]); -- } -- -- uint32_t headroom = dp_packet_headroom(packet); -- struct dp_packet *pkt_clone; -- -- pkt_clone = dp_packet_clone_with_headroom(packet, headroom); -- dp_packet_batch_add(dst, pkt_clone); -- } -- dst->trunc = src->trunc; --} -- --static inline void --dp_packet_delete_batch(struct dp_packet_batch *batch, bool should_steal) --{ -- if (should_steal) { -- struct dp_packet *packet; -- -- DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -- dp_packet_delete(packet); -- } -- dp_packet_batch_init(batch); -- } --} -- --static inline void --dp_packet_batch_init_packet_fields(struct dp_packet_batch *batch) --{ -- struct dp_packet *packet; -- -- DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -- dp_packet_reset_cutlen(packet); -- packet->packet_type = htonl(PT_ETH); -- } --} -- --static inline void --dp_packet_batch_apply_cutlen(struct dp_packet_batch *batch) --{ -- if (batch->trunc) { -- struct dp_packet *packet; -- -- DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -- dp_packet_set_size(packet, dp_packet_get_send_len(packet)); -- dp_packet_reset_cutlen(packet); -- } -- batch->trunc = false; -- } --} -- --static inline void --dp_packet_batch_reset_cutlen(struct dp_packet_batch *batch) --{ -- if (batch->trunc) { -- struct dp_packet *packet; -- -- DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -- dp_packet_reset_cutlen(packet); -- } -- batch->trunc = false; -- } --} -- --/* Returns the RSS hash of the packet 'p'. Note that the returned value is -- * correct only if 'dp_packet_rss_valid(p)' returns 'true'. */ --static inline uint32_t --dp_packet_get_rss_hash(const struct dp_packet *p) --{ -- return *dp_packet_rss_ptr(p); --} -- --static inline void --dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash) --{ -- *dp_packet_rss_ptr(p) = hash; -- *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RSS_HASH; --} -- --static inline bool --dp_packet_rss_valid(const struct dp_packet *p) --{ -- return *dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RSS_HASH; --} -- --static inline void --dp_packet_reset_offload(struct dp_packet *p) --{ -- *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_SUPPORTED_MASK; --} -- --static inline bool --dp_packet_has_flow_mark(const struct dp_packet *p, uint32_t *mark) --{ -- if (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_FLOW_MARK) { -- *mark = *dp_packet_flow_mark_ptr(p); -- return true; -- } -- -- return false; --} -- --static inline void --dp_packet_set_flow_mark(struct dp_packet *p, uint32_t mark) --{ -- *dp_packet_flow_mark_ptr(p) = mark; -- *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_FLOW_MARK; --} -- --/* Returns the L4 cksum offload bitmask. */ --static inline uint64_t --dp_packet_hwol_l4_mask(const struct dp_packet *b) --{ -- return *dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK; --} -- --/* Return true if the packet 'b' requested L4 checksum offload. */ --static inline bool --dp_packet_hwol_tx_l4_checksum(const struct dp_packet *b) --{ -- return !!dp_packet_hwol_l4_mask(b); --} -- --/* Returns 'true' if packet 'b' is marked for TCP segmentation offloading. */ --static inline bool --dp_packet_hwol_is_tso(const struct dp_packet *b) --{ -- return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_TCP_SEG); --} -- --/* Returns 'true' if packet 'b' is marked for IPv4 checksum offloading. */ --static inline bool --dp_packet_hwol_is_ipv4(const struct dp_packet *b) --{ -- return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_IPV4); --} -- --/* Returns 'true' if packet 'b' is marked for TCP checksum offloading. */ --static inline bool --dp_packet_hwol_l4_is_tcp(const struct dp_packet *b) --{ -- return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) == -- DP_PACKET_OL_TX_TCP_CKSUM; --} -- --/* Returns 'true' if packet 'b' is marked for UDP checksum offloading. */ --static inline bool --dp_packet_hwol_l4_is_udp(struct dp_packet *b) --{ -- return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) == -- DP_PACKET_OL_TX_UDP_CKSUM; --} -- --/* Returns 'true' if packet 'b' is marked for SCTP checksum offloading. */ --static inline bool --dp_packet_hwol_l4_is_sctp(struct dp_packet *b) --{ -- return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) == -- DP_PACKET_OL_TX_SCTP_CKSUM; --} -- --/* Mark packet 'b' for IPv4 checksum offloading. */ --static inline void --dp_packet_hwol_set_tx_ipv4(struct dp_packet *b) --{ -- *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_IPV4; --} -- --/* Mark packet 'b' for IPv6 checksum offloading. */ --static inline void --dp_packet_hwol_set_tx_ipv6(struct dp_packet *b) --{ -- *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_IPV6; --} -- --/* Mark packet 'b' for TCP checksum offloading. It implies that either -- * the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */ --static inline void --dp_packet_hwol_set_csum_tcp(struct dp_packet *b) --{ -- *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TCP_CKSUM; --} -- --/* Mark packet 'b' for UDP checksum offloading. It implies that either -- * the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */ --static inline void --dp_packet_hwol_set_csum_udp(struct dp_packet *b) --{ -- *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_UDP_CKSUM; --} -- --/* Mark packet 'b' for SCTP checksum offloading. It implies that either -- * the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */ --static inline void --dp_packet_hwol_set_csum_sctp(struct dp_packet *b) --{ -- *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_SCTP_CKSUM; --} -- --/* Mark packet 'b' for TCP segmentation offloading. It implies that -- * either the packet 'b' is marked for IPv4 or IPv6 checksum offloading -- * and also for TCP checksum offloading. */ --static inline void --dp_packet_hwol_set_tcp_seg(struct dp_packet *b) --{ -- *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TCP_SEG; --} -- --static inline bool --dp_packet_ip_checksum_valid(const struct dp_packet *p) --{ -- return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) == -- DP_PACKET_OL_RX_IP_CKSUM_GOOD; --} -- --static inline bool --dp_packet_ip_checksum_bad(const struct dp_packet *p) --{ -- return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) == -- DP_PACKET_OL_RX_IP_CKSUM_BAD; --} -- --static inline bool --dp_packet_l4_checksum_valid(const struct dp_packet *p) --{ -- return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) == -- DP_PACKET_OL_RX_L4_CKSUM_GOOD; --} -- --static inline bool --dp_packet_l4_checksum_bad(const struct dp_packet *p) --{ -- return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) == -- DP_PACKET_OL_RX_L4_CKSUM_BAD; --} -- --#ifdef __cplusplus --} --#endif -- --#endif /* dp-packet.h */ -Index: openvswitch-2.17.2/include/internal/dp-packet.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/dp-packet.h -@@ -0,0 +1,1092 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef DPBUF_H -+#define DPBUF_H 1 -+ -+#include -+#include -+ -+#ifdef DPDK_NETDEV -+#include -+#include -+#endif -+ -+#include "internal/netdev-afxdp.h" -+#include "internal/netdev-dpdk.h" -+#include "openvswitch/list.h" -+#include "internal/packets.h" -+#include "internal/util.h" -+#include "internal/flow.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+enum OVS_PACKED_ENUM dp_packet_source { -+ DPBUF_MALLOC, /* Obtained via malloc(). */ -+ DPBUF_STACK, /* Un-movable stack space or static buffer. */ -+ DPBUF_STUB, /* Starts on stack, may expand into heap. */ -+ DPBUF_DPDK, /* buffer data is from DPDK allocated memory. -+ * ref to dp_packet_init_dpdk() in dp-packet.c. -+ */ -+ DPBUF_AFXDP, /* Buffer data from XDP frame. */ -+}; -+ -+#define DP_PACKET_CONTEXT_SIZE 64 -+ -+#ifdef DPDK_NETDEV -+#define DEF_OL_FLAG(NAME, DPDK_DEF, GENERIC_DEF) NAME = DPDK_DEF -+#else -+#define DEF_OL_FLAG(NAME, DPDK_DEF, GENERIC_DEF) NAME = GENERIC_DEF -+#endif -+ -+/* Bit masks for the 'ol_flags' member of the 'dp_packet' structure. */ -+enum dp_packet_offload_mask { -+ /* Value 0 is not used. */ -+ /* Is the 'rss_hash' valid? */ -+ DEF_OL_FLAG(DP_PACKET_OL_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, 0x1), -+ /* Is the 'flow_mark' valid? */ -+ DEF_OL_FLAG(DP_PACKET_OL_FLOW_MARK, RTE_MBUF_F_RX_FDIR_ID, 0x2), -+ /* Bad L4 checksum in the packet. */ -+ DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_BAD, RTE_MBUF_F_RX_L4_CKSUM_BAD, 0x4), -+ /* Bad IP checksum in the packet. */ -+ DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_BAD, RTE_MBUF_F_RX_IP_CKSUM_BAD, 0x8), -+ /* Valid L4 checksum in the packet. */ -+ DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_GOOD, -+ 0x10), -+ /* Valid IP checksum in the packet. */ -+ DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_GOOD, -+ 0x20), -+ /* TCP Segmentation Offload. */ -+ DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_SEG, RTE_MBUF_F_TX_TCP_SEG, 0x40), -+ /* Offloaded packet is IPv4. */ -+ DEF_OL_FLAG(DP_PACKET_OL_TX_IPV4, RTE_MBUF_F_TX_IPV4, 0x80), -+ /* Offloaded packet is IPv6. */ -+ DEF_OL_FLAG(DP_PACKET_OL_TX_IPV6, RTE_MBUF_F_TX_IPV6, 0x100), -+ /* Offload TCP checksum. */ -+ DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_CKSUM, RTE_MBUF_F_TX_TCP_CKSUM, 0x200), -+ /* Offload UDP checksum. */ -+ DEF_OL_FLAG(DP_PACKET_OL_TX_UDP_CKSUM, RTE_MBUF_F_TX_UDP_CKSUM, 0x400), -+ /* Offload SCTP checksum. */ -+ DEF_OL_FLAG(DP_PACKET_OL_TX_SCTP_CKSUM, RTE_MBUF_F_TX_SCTP_CKSUM, 0x800), -+ /* Adding new field requires adding to DP_PACKET_OL_SUPPORTED_MASK. */ -+}; -+ -+#define DP_PACKET_OL_SUPPORTED_MASK (DP_PACKET_OL_RSS_HASH | \ -+ DP_PACKET_OL_FLOW_MARK | \ -+ DP_PACKET_OL_RX_L4_CKSUM_BAD | \ -+ DP_PACKET_OL_RX_IP_CKSUM_BAD | \ -+ DP_PACKET_OL_RX_L4_CKSUM_GOOD | \ -+ DP_PACKET_OL_RX_IP_CKSUM_GOOD | \ -+ DP_PACKET_OL_TX_TCP_SEG | \ -+ DP_PACKET_OL_TX_IPV4 | \ -+ DP_PACKET_OL_TX_IPV6 | \ -+ DP_PACKET_OL_TX_TCP_CKSUM | \ -+ DP_PACKET_OL_TX_UDP_CKSUM | \ -+ DP_PACKET_OL_TX_SCTP_CKSUM) -+ -+#define DP_PACKET_OL_TX_L4_MASK (DP_PACKET_OL_TX_TCP_CKSUM | \ -+ DP_PACKET_OL_TX_UDP_CKSUM | \ -+ DP_PACKET_OL_TX_SCTP_CKSUM) -+#define DP_PACKET_OL_RX_IP_CKSUM_MASK (DP_PACKET_OL_RX_IP_CKSUM_GOOD | \ -+ DP_PACKET_OL_RX_IP_CKSUM_BAD) -+#define DP_PACKET_OL_RX_L4_CKSUM_MASK (DP_PACKET_OL_RX_L4_CKSUM_GOOD | \ -+ DP_PACKET_OL_RX_L4_CKSUM_BAD) -+ -+/* Buffer for holding packet data. A dp_packet is automatically reallocated -+ * as necessary if it grows too large for the available memory. -+ * By default the packet type is set to Ethernet (PT_ETH). -+ */ -+struct dp_packet { -+#ifdef DPDK_NETDEV -+ struct rte_mbuf mbuf; /* DPDK mbuf */ -+#else -+ void *base_; /* First byte of allocated space. */ -+ uint16_t allocated_; /* Number of bytes allocated. */ -+ uint16_t data_ofs; /* First byte actually in use. */ -+ uint32_t size_; /* Number of bytes in use. */ -+ uint32_t ol_flags; /* Offloading flags. */ -+ uint32_t rss_hash; /* Packet hash. */ -+ uint32_t flow_mark; /* Packet flow mark. */ -+#endif -+ enum dp_packet_source source; /* Source of memory allocated as 'base'. */ -+ -+ /* All the following elements of this struct are copied in a single call -+ * of memcpy in dp_packet_clone_with_headroom. */ -+ uint16_t l2_pad_size; /* Detected l2 padding size. -+ * Padding is non-pullable. */ -+ uint16_t l2_5_ofs; /* MPLS label stack offset, or UINT16_MAX */ -+ uint16_t l3_ofs; /* Network-level header offset, -+ * or UINT16_MAX. */ -+ uint16_t l4_ofs; /* Transport-level header offset, -+ or UINT16_MAX. */ -+ uint32_t cutlen; /* length in bytes to cut from the end. */ -+ ovs_be32 packet_type; /* Packet type as defined in OpenFlow */ -+ union { -+ struct pkt_metadata md; -+ uint64_t data[DP_PACKET_CONTEXT_SIZE / 8]; -+ }; -+}; -+ -+#if HAVE_AF_XDP -+struct dp_packet_afxdp { -+ struct umem_pool *mpool; -+ struct dp_packet packet; -+}; -+#endif -+ -+static inline void *dp_packet_data(const struct dp_packet *); -+static inline void dp_packet_set_data(struct dp_packet *, void *); -+static inline void *dp_packet_base(const struct dp_packet *); -+static inline void dp_packet_set_base(struct dp_packet *, void *); -+ -+static inline uint32_t dp_packet_size(const struct dp_packet *); -+static inline void dp_packet_set_size(struct dp_packet *, uint32_t); -+ -+static inline uint16_t dp_packet_get_allocated(const struct dp_packet *); -+static inline void dp_packet_set_allocated(struct dp_packet *, uint16_t); -+ -+void *dp_packet_resize_l2(struct dp_packet *, int increment); -+void *dp_packet_resize_l2_5(struct dp_packet *, int increment); -+static inline void *dp_packet_eth(const struct dp_packet *); -+static inline void dp_packet_reset_offsets(struct dp_packet *); -+static inline uint16_t dp_packet_l2_pad_size(const struct dp_packet *); -+static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint16_t); -+static inline void *dp_packet_l2_5(const struct dp_packet *); -+static inline void dp_packet_set_l2_5(struct dp_packet *, void *); -+static inline void *dp_packet_l3(const struct dp_packet *); -+static inline void dp_packet_set_l3(struct dp_packet *, void *); -+static inline void *dp_packet_l4(const struct dp_packet *); -+static inline void dp_packet_set_l4(struct dp_packet *, void *); -+static inline size_t dp_packet_l4_size(const struct dp_packet *); -+static inline const void *dp_packet_get_tcp_payload(const struct dp_packet *); -+static inline const void *dp_packet_get_udp_payload(const struct dp_packet *); -+static inline const void *dp_packet_get_sctp_payload(const struct dp_packet *); -+static inline const void *dp_packet_get_icmp_payload(const struct dp_packet *); -+static inline const void *dp_packet_get_nd_payload(const struct dp_packet *); -+ -+void dp_packet_use(struct dp_packet *, void *, size_t); -+void dp_packet_use_stub(struct dp_packet *, void *, size_t); -+void dp_packet_use_const(struct dp_packet *, const void *, size_t); -+#if HAVE_AF_XDP -+void dp_packet_use_afxdp(struct dp_packet *, void *, size_t, size_t); -+#endif -+void dp_packet_init_dpdk(struct dp_packet *); -+ -+void dp_packet_init(struct dp_packet *, size_t); -+void dp_packet_uninit(struct dp_packet *); -+ -+struct dp_packet *dp_packet_new(size_t); -+struct dp_packet *dp_packet_new_with_headroom(size_t, size_t headroom); -+struct dp_packet *dp_packet_clone(const struct dp_packet *); -+struct dp_packet *dp_packet_clone_with_headroom(const struct dp_packet *, -+ size_t headroom); -+struct dp_packet *dp_packet_clone_data(const void *, size_t); -+struct dp_packet *dp_packet_clone_data_with_headroom(const void *, size_t, -+ size_t headroom); -+void dp_packet_resize(struct dp_packet *b, size_t new_headroom, -+ size_t new_tailroom); -+static inline void dp_packet_delete(struct dp_packet *); -+static inline void dp_packet_swap(struct dp_packet *, struct dp_packet *); -+ -+static inline void *dp_packet_at(const struct dp_packet *, size_t offset, -+ size_t size); -+static inline void *dp_packet_at_assert(const struct dp_packet *, -+ size_t offset, size_t size); -+static inline void *dp_packet_tail(const struct dp_packet *); -+static inline void *dp_packet_end(const struct dp_packet *); -+ -+void *dp_packet_put_uninit(struct dp_packet *, size_t); -+void *dp_packet_put_zeros(struct dp_packet *, size_t); -+void *dp_packet_put(struct dp_packet *, const void *, size_t); -+char *dp_packet_put_hex(struct dp_packet *, const char *s, size_t *n); -+void dp_packet_reserve(struct dp_packet *, size_t); -+void dp_packet_reserve_with_tailroom(struct dp_packet *, size_t headroom, -+ size_t tailroom); -+void *dp_packet_push_uninit(struct dp_packet *, size_t); -+void *dp_packet_push_zeros(struct dp_packet *, size_t); -+void *dp_packet_push(struct dp_packet *, const void *, size_t); -+ -+static inline size_t dp_packet_headroom(const struct dp_packet *); -+static inline size_t dp_packet_tailroom(const struct dp_packet *); -+void dp_packet_prealloc_headroom(struct dp_packet *, size_t); -+void dp_packet_prealloc_tailroom(struct dp_packet *, size_t); -+void dp_packet_shift(struct dp_packet *, int); -+ -+static inline void dp_packet_clear(struct dp_packet *); -+static inline void *dp_packet_pull(struct dp_packet *, size_t); -+static inline void *dp_packet_try_pull(struct dp_packet *, size_t); -+ -+void *dp_packet_steal_data(struct dp_packet *); -+ -+static inline bool dp_packet_equal(const struct dp_packet *, -+ const struct dp_packet *); -+ -+ -+/* Frees memory that 'b' points to, as well as 'b' itself. */ -+static inline void -+dp_packet_delete(struct dp_packet *b) -+{ -+ if (b) { -+ if (b->source == DPBUF_DPDK) { -+ /* If this dp_packet was allocated by DPDK it must have been -+ * created as a dp_packet */ -+ free_dpdk_buf((struct dp_packet*) b); -+ return; -+ } -+ -+ if (b->source == DPBUF_AFXDP) { -+ free_afxdp_buf(b); -+ return; -+ } -+ -+ dp_packet_uninit(b); -+ free(b); -+ } -+} -+ -+/* Swaps content of two packets. */ -+static inline void -+dp_packet_swap(struct dp_packet *a, struct dp_packet *b) -+{ -+ ovs_assert(a->source == DPBUF_MALLOC || a->source == DPBUF_STUB); -+ ovs_assert(b->source == DPBUF_MALLOC || b->source == DPBUF_STUB); -+ struct dp_packet c = *a; -+ -+ *a = *b; -+ *b = c; -+} -+ -+/* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to -+ * byte 'offset'. Otherwise, returns a null pointer. */ -+static inline void * -+dp_packet_at(const struct dp_packet *b, size_t offset, size_t size) -+{ -+ return offset + size <= dp_packet_size(b) -+ ? (char *) dp_packet_data(b) + offset -+ : NULL; -+} -+ -+/* Returns a pointer to byte 'offset' in 'b', which must contain at least -+ * 'offset + size' bytes of data. */ -+static inline void * -+dp_packet_at_assert(const struct dp_packet *b, size_t offset, size_t size) -+{ -+ ovs_assert(offset + size <= dp_packet_size(b)); -+ return ((char *) dp_packet_data(b)) + offset; -+} -+ -+/* Returns a pointer to byte following the last byte of data in use in 'b'. */ -+static inline void * -+dp_packet_tail(const struct dp_packet *b) -+{ -+ return (char *) dp_packet_data(b) + dp_packet_size(b); -+} -+ -+/* Returns a pointer to byte following the last byte allocated for use (but -+ * not necessarily in use) in 'b'. */ -+static inline void * -+dp_packet_end(const struct dp_packet *b) -+{ -+ return (char *) dp_packet_base(b) + dp_packet_get_allocated(b); -+} -+ -+/* Returns the number of bytes of headroom in 'b', that is, the number of bytes -+ * of unused space in dp_packet 'b' before the data that is in use. (Most -+ * commonly, the data in a dp_packet is at its beginning, and thus the -+ * dp_packet's headroom is 0.) */ -+static inline size_t -+dp_packet_headroom(const struct dp_packet *b) -+{ -+ return (char *) dp_packet_data(b) - (char *) dp_packet_base(b); -+} -+ -+/* Returns the number of bytes that may be appended to the tail end of -+ * dp_packet 'b' before the dp_packet must be reallocated. */ -+static inline size_t -+dp_packet_tailroom(const struct dp_packet *b) -+{ -+ return (char *) dp_packet_end(b) - (char *) dp_packet_tail(b); -+} -+ -+/* Clears any data from 'b'. */ -+static inline void -+dp_packet_clear(struct dp_packet *b) -+{ -+ dp_packet_set_data(b, dp_packet_base(b)); -+ dp_packet_set_size(b, 0); -+} -+ -+/* Removes 'size' bytes from the head end of 'b', which must contain at least -+ * 'size' bytes of data. Returns the first byte of data removed. */ -+static inline void * -+dp_packet_pull(struct dp_packet *b, size_t size) -+{ -+ void *data = dp_packet_data(b); -+ ovs_assert(dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size); -+ dp_packet_set_data(b, (char *) dp_packet_data(b) + size); -+ dp_packet_set_size(b, dp_packet_size(b) - size); -+ return data; -+} -+ -+/* If 'b' has at least 'size' bytes of data, removes that many bytes from the -+ * head end of 'b' and returns the first byte removed. Otherwise, returns a -+ * null pointer without modifying 'b'. */ -+static inline void * -+dp_packet_try_pull(struct dp_packet *b, size_t size) -+{ -+ return dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size -+ ? dp_packet_pull(b, size) : NULL; -+} -+ -+static inline bool -+dp_packet_equal(const struct dp_packet *a, const struct dp_packet *b) -+{ -+ return dp_packet_size(a) == dp_packet_size(b) && -+ !memcmp(dp_packet_data(a), dp_packet_data(b), dp_packet_size(a)); -+} -+ -+static inline bool -+dp_packet_is_eth(const struct dp_packet *b) -+{ -+ return b->packet_type == htonl(PT_ETH); -+} -+ -+/* Get the start of the Ethernet frame. 'l3_ofs' marks the end of the l2 -+ * headers, so return NULL if it is not set. */ -+static inline void * -+dp_packet_eth(const struct dp_packet *b) -+{ -+ return (dp_packet_is_eth(b) && b->l3_ofs != UINT16_MAX) -+ ? dp_packet_data(b) : NULL; -+} -+ -+/* Resets all layer offsets. 'l3' offset must be set before 'l2' can be -+ * retrieved. */ -+static inline void -+dp_packet_reset_offsets(struct dp_packet *b) -+{ -+ b->l2_pad_size = 0; -+ b->l2_5_ofs = UINT16_MAX; -+ b->l3_ofs = UINT16_MAX; -+ b->l4_ofs = UINT16_MAX; -+} -+ -+static inline uint16_t -+dp_packet_l2_pad_size(const struct dp_packet *b) -+{ -+ return b->l2_pad_size; -+} -+ -+static inline void -+dp_packet_set_l2_pad_size(struct dp_packet *b, uint16_t pad_size) -+{ -+ ovs_assert(pad_size <= dp_packet_size(b)); -+ b->l2_pad_size = pad_size; -+} -+ -+static inline void * -+dp_packet_l2_5(const struct dp_packet *b) -+{ -+ return b->l2_5_ofs != UINT16_MAX -+ ? (char *) dp_packet_data(b) + b->l2_5_ofs -+ : NULL; -+} -+ -+static inline void -+dp_packet_set_l2_5(struct dp_packet *b, void *l2_5) -+{ -+ b->l2_5_ofs = l2_5 -+ ? (char *) l2_5 - (char *) dp_packet_data(b) -+ : UINT16_MAX; -+} -+ -+static inline void * -+dp_packet_l3(const struct dp_packet *b) -+{ -+ return b->l3_ofs != UINT16_MAX -+ ? (char *) dp_packet_data(b) + b->l3_ofs -+ : NULL; -+} -+ -+static inline void -+dp_packet_set_l3(struct dp_packet *b, void *l3) -+{ -+ b->l3_ofs = l3 ? (char *) l3 - (char *) dp_packet_data(b) : UINT16_MAX; -+} -+ -+static inline void * -+dp_packet_l4(const struct dp_packet *b) -+{ -+ return b->l4_ofs != UINT16_MAX -+ ? (char *) dp_packet_data(b) + b->l4_ofs -+ : NULL; -+} -+ -+static inline void -+dp_packet_set_l4(struct dp_packet *b, void *l4) -+{ -+ b->l4_ofs = l4 ? (char *) l4 - (char *) dp_packet_data(b) : UINT16_MAX; -+} -+ -+/* Returns the size of the packet from the beginning of the L3 header to the -+ * end of the L3 payload. Hence L2 padding is not included. */ -+static inline size_t -+dp_packet_l3_size(const struct dp_packet *b) -+{ -+ return OVS_LIKELY(b->l3_ofs != UINT16_MAX) -+ ? (const char *)dp_packet_tail(b) - (const char *)dp_packet_l3(b) -+ - dp_packet_l2_pad_size(b) -+ : 0; -+} -+ -+/* Returns the size of the packet from the beginning of the L4 header to the -+ * end of the L4 payload. Hence L2 padding is not included. */ -+static inline size_t -+dp_packet_l4_size(const struct dp_packet *b) -+{ -+ return OVS_LIKELY(b->l4_ofs != UINT16_MAX) -+ ? (const char *)dp_packet_tail(b) - (const char *)dp_packet_l4(b) -+ - dp_packet_l2_pad_size(b) -+ : 0; -+} -+ -+static inline const void * -+dp_packet_get_tcp_payload(const struct dp_packet *b) -+{ -+ size_t l4_size = dp_packet_l4_size(b); -+ -+ if (OVS_LIKELY(l4_size >= TCP_HEADER_LEN)) { -+ struct tcp_header *tcp = dp_packet_l4(b); -+ int tcp_len = TCP_OFFSET(tcp->tcp_ctl) * 4; -+ -+ if (OVS_LIKELY(tcp_len >= TCP_HEADER_LEN && tcp_len <= l4_size)) { -+ return (const char *)tcp + tcp_len; -+ } -+ } -+ return NULL; -+} -+ -+static inline uint32_t -+dp_packet_get_tcp_payload_length(const struct dp_packet *pkt) -+{ -+ const char *tcp_payload = dp_packet_get_tcp_payload(pkt); -+ if (tcp_payload) { -+ return ((char *) dp_packet_tail(pkt) - dp_packet_l2_pad_size(pkt) -+ - tcp_payload); -+ } else { -+ return 0; -+ } -+} -+ -+static inline const void * -+dp_packet_get_udp_payload(const struct dp_packet *b) -+{ -+ return OVS_LIKELY(dp_packet_l4_size(b) >= UDP_HEADER_LEN) -+ ? (const char *)dp_packet_l4(b) + UDP_HEADER_LEN : NULL; -+} -+ -+static inline const void * -+dp_packet_get_sctp_payload(const struct dp_packet *b) -+{ -+ return OVS_LIKELY(dp_packet_l4_size(b) >= SCTP_HEADER_LEN) -+ ? (const char *)dp_packet_l4(b) + SCTP_HEADER_LEN : NULL; -+} -+ -+static inline const void * -+dp_packet_get_icmp_payload(const struct dp_packet *b) -+{ -+ return OVS_LIKELY(dp_packet_l4_size(b) >= ICMP_HEADER_LEN) -+ ? (const char *)dp_packet_l4(b) + ICMP_HEADER_LEN : NULL; -+} -+ -+static inline const void * -+dp_packet_get_nd_payload(const struct dp_packet *b) -+{ -+ return OVS_LIKELY(dp_packet_l4_size(b) >= ND_MSG_LEN) -+ ? (const char *)dp_packet_l4(b) + ND_MSG_LEN : NULL; -+} -+ -+#ifdef DPDK_NETDEV -+static inline uint64_t * -+dp_packet_ol_flags_ptr(const struct dp_packet *b) -+{ -+ return CONST_CAST(uint64_t *, &b->mbuf.ol_flags); -+} -+ -+static inline uint32_t * -+dp_packet_rss_ptr(const struct dp_packet *b) -+{ -+ return CONST_CAST(uint32_t *, &b->mbuf.hash.rss); -+} -+ -+static inline uint32_t * -+dp_packet_flow_mark_ptr(const struct dp_packet *b) -+{ -+ return CONST_CAST(uint32_t *, &b->mbuf.hash.fdir.hi); -+} -+ -+#else -+static inline uint32_t * -+dp_packet_ol_flags_ptr(const struct dp_packet *b) -+{ -+ return CONST_CAST(uint32_t *, &b->ol_flags); -+} -+ -+static inline uint32_t * -+dp_packet_rss_ptr(const struct dp_packet *b) -+{ -+ return CONST_CAST(uint32_t *, &b->rss_hash); -+} -+ -+static inline uint32_t * -+dp_packet_flow_mark_ptr(const struct dp_packet *b) -+{ -+ return CONST_CAST(uint32_t *, &b->flow_mark); -+} -+#endif -+ -+#ifdef DPDK_NETDEV -+BUILD_ASSERT_DECL(offsetof(struct dp_packet, mbuf) == 0); -+ -+static inline void -+dp_packet_init_specific(struct dp_packet *p) -+{ -+ /* This initialization is needed for packets that do not come from DPDK -+ * interfaces, when vswitchd is built with --with-dpdk. */ -+ p->mbuf.ol_flags = p->mbuf.tx_offload = p->mbuf.packet_type = 0; -+ p->mbuf.nb_segs = 1; -+ p->mbuf.next = NULL; -+} -+ -+static inline void * -+dp_packet_base(const struct dp_packet *b) -+{ -+ return b->mbuf.buf_addr; -+} -+ -+static inline void -+dp_packet_set_base(struct dp_packet *b, void *d) -+{ -+ b->mbuf.buf_addr = d; -+} -+ -+static inline uint32_t -+dp_packet_size(const struct dp_packet *b) -+{ -+ return b->mbuf.pkt_len; -+} -+ -+static inline void -+dp_packet_set_size(struct dp_packet *b, uint32_t v) -+{ -+ /* netdev-dpdk does not currently support segmentation; consequently, for -+ * all intents and purposes, 'data_len' (16 bit) and 'pkt_len' (32 bit) may -+ * be used interchangably. -+ * -+ * On the datapath, it is expected that the size of packets -+ * (and thus 'v') will always be <= UINT16_MAX; this means that there is no -+ * loss of accuracy in assigning 'v' to 'data_len'. -+ */ -+ b->mbuf.data_len = (uint16_t)v; /* Current seg length. */ -+ b->mbuf.pkt_len = v; /* Total length of all segments linked to -+ * this segment. */ -+} -+ -+static inline uint16_t -+__packet_data(const struct dp_packet *b) -+{ -+ return b->mbuf.data_off; -+} -+ -+static inline void -+__packet_set_data(struct dp_packet *b, uint16_t v) -+{ -+ b->mbuf.data_off = v; -+} -+ -+static inline uint16_t -+dp_packet_get_allocated(const struct dp_packet *b) -+{ -+ return b->mbuf.buf_len; -+} -+ -+static inline void -+dp_packet_set_allocated(struct dp_packet *b, uint16_t s) -+{ -+ b->mbuf.buf_len = s; -+} -+ -+#else /* DPDK_NETDEV */ -+ -+static inline void -+dp_packet_init_specific(struct dp_packet *p OVS_UNUSED) -+{ -+ /* There are no implementation-specific fields for initialization. */ -+} -+ -+static inline void * -+dp_packet_base(const struct dp_packet *b) -+{ -+ return b->base_; -+} -+ -+static inline void -+dp_packet_set_base(struct dp_packet *b, void *d) -+{ -+ b->base_ = d; -+} -+ -+static inline uint32_t -+dp_packet_size(const struct dp_packet *b) -+{ -+ return b->size_; -+} -+ -+static inline void -+dp_packet_set_size(struct dp_packet *b, uint32_t v) -+{ -+ b->size_ = v; -+} -+ -+static inline uint16_t -+__packet_data(const struct dp_packet *b) -+{ -+ return b->data_ofs; -+} -+ -+static inline void -+__packet_set_data(struct dp_packet *b, uint16_t v) -+{ -+ b->data_ofs = v; -+} -+ -+static inline uint16_t -+dp_packet_get_allocated(const struct dp_packet *b) -+{ -+ return b->allocated_; -+} -+ -+static inline void -+dp_packet_set_allocated(struct dp_packet *b, uint16_t s) -+{ -+ b->allocated_ = s; -+} -+ -+#endif /* DPDK_NETDEV */ -+ -+static inline void -+dp_packet_reset_cutlen(struct dp_packet *b) -+{ -+ b->cutlen = 0; -+} -+ -+static inline uint32_t -+dp_packet_set_cutlen(struct dp_packet *b, uint32_t max_len) -+{ -+ if (max_len < ETH_HEADER_LEN) { -+ max_len = ETH_HEADER_LEN; -+ } -+ -+ if (max_len >= dp_packet_size(b)) { -+ b->cutlen = 0; -+ } else { -+ b->cutlen = dp_packet_size(b) - max_len; -+ } -+ return b->cutlen; -+} -+ -+static inline uint32_t -+dp_packet_get_cutlen(const struct dp_packet *b) -+{ -+ /* Always in valid range if user uses dp_packet_set_cutlen. */ -+ return b->cutlen; -+} -+ -+static inline uint32_t -+dp_packet_get_send_len(const struct dp_packet *b) -+{ -+ return dp_packet_size(b) - dp_packet_get_cutlen(b); -+} -+ -+static inline void * -+dp_packet_data(const struct dp_packet *b) -+{ -+ return __packet_data(b) != UINT16_MAX -+ ? (char *) dp_packet_base(b) + __packet_data(b) : NULL; -+} -+ -+static inline void -+dp_packet_set_data(struct dp_packet *b, void *data) -+{ -+ if (data) { -+ __packet_set_data(b, (char *) data - (char *) dp_packet_base(b)); -+ } else { -+ __packet_set_data(b, UINT16_MAX); -+ } -+} -+ -+static inline void -+dp_packet_reset_packet(struct dp_packet *b, int off) -+{ -+ dp_packet_set_size(b, dp_packet_size(b) - off); -+ dp_packet_set_data(b, ((unsigned char *) dp_packet_data(b) + off)); -+ dp_packet_reset_offsets(b); -+} -+ -+enum { NETDEV_MAX_BURST = 32 }; /* Maximum number packets in a batch. */ -+ -+struct dp_packet_batch { -+ size_t count; -+ bool trunc; /* true if the batch needs truncate. */ -+ struct dp_packet *packets[NETDEV_MAX_BURST]; -+}; -+ -+static inline void -+dp_packet_batch_init(struct dp_packet_batch *batch) -+{ -+ batch->count = 0; -+ batch->trunc = false; -+} -+ -+static inline void -+dp_packet_batch_add__(struct dp_packet_batch *batch, -+ struct dp_packet *packet, size_t limit) -+{ -+ if (batch->count < limit) { -+ batch->packets[batch->count++] = packet; -+ } else { -+ dp_packet_delete(packet); -+ } -+} -+ -+/* When the batch is full, 'packet' will be dropped and freed. */ -+static inline void -+dp_packet_batch_add(struct dp_packet_batch *batch, struct dp_packet *packet) -+{ -+ dp_packet_batch_add__(batch, packet, NETDEV_MAX_BURST); -+} -+ -+static inline size_t -+dp_packet_batch_size(const struct dp_packet_batch *batch) -+{ -+ return batch->count; -+} -+ -+/* Clear 'batch' for refill. Use dp_packet_batch_refill() to add -+ * packets back into the 'batch'. */ -+static inline void -+dp_packet_batch_refill_init(struct dp_packet_batch *batch) -+{ -+ batch->count = 0; -+}; -+ -+static inline void -+dp_packet_batch_refill(struct dp_packet_batch *batch, -+ struct dp_packet *packet, size_t idx) -+{ -+ dp_packet_batch_add__(batch, packet, MIN(NETDEV_MAX_BURST, idx + 1)); -+} -+ -+static inline void -+dp_packet_batch_init_packet(struct dp_packet_batch *batch, struct dp_packet *p) -+{ -+ dp_packet_batch_init(batch); -+ batch->count = 1; -+ batch->packets[0] = p; -+} -+ -+static inline bool -+dp_packet_batch_is_empty(const struct dp_packet_batch *batch) -+{ -+ return !dp_packet_batch_size(batch); -+} -+ -+static inline bool -+dp_packet_batch_is_full(const struct dp_packet_batch *batch) -+{ -+ return dp_packet_batch_size(batch) == NETDEV_MAX_BURST; -+} -+ -+#define DP_PACKET_BATCH_FOR_EACH(IDX, PACKET, BATCH) \ -+ for (size_t IDX = 0; IDX < dp_packet_batch_size(BATCH); IDX++) \ -+ if (PACKET = BATCH->packets[IDX], true) -+ -+/* Use this macro for cases where some packets in the 'BATCH' may be -+ * dropped after going through each packet in the 'BATCH'. -+ * -+ * For packets to stay in the 'BATCH', they need to be refilled back -+ * into the 'BATCH' by calling dp_packet_batch_refill(). Caller owns -+ * the packets that are not refilled. -+ * -+ * Caller needs to supply 'SIZE', that stores the current number of -+ * packets in 'BATCH'. It is best to declare this variable with -+ * the 'const' modifier since it should not be modified by -+ * the iterator. */ -+#define DP_PACKET_BATCH_REFILL_FOR_EACH(IDX, SIZE, PACKET, BATCH) \ -+ for (dp_packet_batch_refill_init(BATCH), IDX=0; IDX < SIZE; IDX++) \ -+ if (PACKET = BATCH->packets[IDX], true) -+ -+static inline void -+dp_packet_batch_clone(struct dp_packet_batch *dst, -+ struct dp_packet_batch *src) -+{ -+ struct dp_packet *packet; -+ -+ dp_packet_batch_init(dst); -+ DP_PACKET_BATCH_FOR_EACH (i, packet, src) { -+ if (i + 1 < dp_packet_batch_size(src)) { -+ OVS_PREFETCH(src->packets[i + 1]); -+ } -+ -+ uint32_t headroom = dp_packet_headroom(packet); -+ struct dp_packet *pkt_clone; -+ -+ pkt_clone = dp_packet_clone_with_headroom(packet, headroom); -+ dp_packet_batch_add(dst, pkt_clone); -+ } -+ dst->trunc = src->trunc; -+} -+ -+static inline void -+dp_packet_delete_batch(struct dp_packet_batch *batch, bool should_steal) -+{ -+ if (should_steal) { -+ struct dp_packet *packet; -+ -+ DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -+ dp_packet_delete(packet); -+ } -+ dp_packet_batch_init(batch); -+ } -+} -+ -+static inline void -+dp_packet_batch_init_packet_fields(struct dp_packet_batch *batch) -+{ -+ struct dp_packet *packet; -+ -+ DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -+ dp_packet_reset_cutlen(packet); -+ packet->packet_type = htonl(PT_ETH); -+ } -+} -+ -+static inline void -+dp_packet_batch_apply_cutlen(struct dp_packet_batch *batch) -+{ -+ if (batch->trunc) { -+ struct dp_packet *packet; -+ -+ DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -+ dp_packet_set_size(packet, dp_packet_get_send_len(packet)); -+ dp_packet_reset_cutlen(packet); -+ } -+ batch->trunc = false; -+ } -+} -+ -+static inline void -+dp_packet_batch_reset_cutlen(struct dp_packet_batch *batch) -+{ -+ if (batch->trunc) { -+ struct dp_packet *packet; -+ -+ DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { -+ dp_packet_reset_cutlen(packet); -+ } -+ batch->trunc = false; -+ } -+} -+ -+/* Returns the RSS hash of the packet 'p'. Note that the returned value is -+ * correct only if 'dp_packet_rss_valid(p)' returns 'true'. */ -+static inline uint32_t -+dp_packet_get_rss_hash(const struct dp_packet *p) -+{ -+ return *dp_packet_rss_ptr(p); -+} -+ -+static inline void -+dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash) -+{ -+ *dp_packet_rss_ptr(p) = hash; -+ *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RSS_HASH; -+} -+ -+static inline bool -+dp_packet_rss_valid(const struct dp_packet *p) -+{ -+ return *dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RSS_HASH; -+} -+ -+static inline void -+dp_packet_reset_offload(struct dp_packet *p) -+{ -+ *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_SUPPORTED_MASK; -+} -+ -+static inline bool -+dp_packet_has_flow_mark(const struct dp_packet *p, uint32_t *mark) -+{ -+ if (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_FLOW_MARK) { -+ *mark = *dp_packet_flow_mark_ptr(p); -+ return true; -+ } -+ -+ return false; -+} -+ -+static inline void -+dp_packet_set_flow_mark(struct dp_packet *p, uint32_t mark) -+{ -+ *dp_packet_flow_mark_ptr(p) = mark; -+ *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_FLOW_MARK; -+} -+ -+/* Returns the L4 cksum offload bitmask. */ -+static inline uint64_t -+dp_packet_hwol_l4_mask(const struct dp_packet *b) -+{ -+ return *dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK; -+} -+ -+/* Return true if the packet 'b' requested L4 checksum offload. */ -+static inline bool -+dp_packet_hwol_tx_l4_checksum(const struct dp_packet *b) -+{ -+ return !!dp_packet_hwol_l4_mask(b); -+} -+ -+/* Returns 'true' if packet 'b' is marked for TCP segmentation offloading. */ -+static inline bool -+dp_packet_hwol_is_tso(const struct dp_packet *b) -+{ -+ return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_TCP_SEG); -+} -+ -+/* Returns 'true' if packet 'b' is marked for IPv4 checksum offloading. */ -+static inline bool -+dp_packet_hwol_is_ipv4(const struct dp_packet *b) -+{ -+ return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_IPV4); -+} -+ -+/* Returns 'true' if packet 'b' is marked for TCP checksum offloading. */ -+static inline bool -+dp_packet_hwol_l4_is_tcp(const struct dp_packet *b) -+{ -+ return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) == -+ DP_PACKET_OL_TX_TCP_CKSUM; -+} -+ -+/* Returns 'true' if packet 'b' is marked for UDP checksum offloading. */ -+static inline bool -+dp_packet_hwol_l4_is_udp(struct dp_packet *b) -+{ -+ return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) == -+ DP_PACKET_OL_TX_UDP_CKSUM; -+} -+ -+/* Returns 'true' if packet 'b' is marked for SCTP checksum offloading. */ -+static inline bool -+dp_packet_hwol_l4_is_sctp(struct dp_packet *b) -+{ -+ return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) == -+ DP_PACKET_OL_TX_SCTP_CKSUM; -+} -+ -+/* Mark packet 'b' for IPv4 checksum offloading. */ -+static inline void -+dp_packet_hwol_set_tx_ipv4(struct dp_packet *b) -+{ -+ *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_IPV4; -+} -+ -+/* Mark packet 'b' for IPv6 checksum offloading. */ -+static inline void -+dp_packet_hwol_set_tx_ipv6(struct dp_packet *b) -+{ -+ *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_IPV6; -+} -+ -+/* Mark packet 'b' for TCP checksum offloading. It implies that either -+ * the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */ -+static inline void -+dp_packet_hwol_set_csum_tcp(struct dp_packet *b) -+{ -+ *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TCP_CKSUM; -+} -+ -+/* Mark packet 'b' for UDP checksum offloading. It implies that either -+ * the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */ -+static inline void -+dp_packet_hwol_set_csum_udp(struct dp_packet *b) -+{ -+ *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_UDP_CKSUM; -+} -+ -+/* Mark packet 'b' for SCTP checksum offloading. It implies that either -+ * the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */ -+static inline void -+dp_packet_hwol_set_csum_sctp(struct dp_packet *b) -+{ -+ *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_SCTP_CKSUM; -+} -+ -+/* Mark packet 'b' for TCP segmentation offloading. It implies that -+ * either the packet 'b' is marked for IPv4 or IPv6 checksum offloading -+ * and also for TCP checksum offloading. */ -+static inline void -+dp_packet_hwol_set_tcp_seg(struct dp_packet *b) -+{ -+ *dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TCP_SEG; -+} -+ -+static inline bool -+dp_packet_ip_checksum_valid(const struct dp_packet *p) -+{ -+ return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) == -+ DP_PACKET_OL_RX_IP_CKSUM_GOOD; -+} -+ -+static inline bool -+dp_packet_ip_checksum_bad(const struct dp_packet *p) -+{ -+ return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) == -+ DP_PACKET_OL_RX_IP_CKSUM_BAD; -+} -+ -+static inline bool -+dp_packet_l4_checksum_valid(const struct dp_packet *p) -+{ -+ return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) == -+ DP_PACKET_OL_RX_L4_CKSUM_GOOD; -+} -+ -+static inline bool -+dp_packet_l4_checksum_bad(const struct dp_packet *p) -+{ -+ return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) == -+ DP_PACKET_OL_RX_L4_CKSUM_BAD; -+} -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* dp-packet.h */ -Index: openvswitch-2.17.2/lib/flow.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/flow.h -+++ /dev/null -@@ -1,1215 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --#ifndef FLOW_H --#define FLOW_H 1 -- --#include --#include --#include --#include --#include --#include --#include "bitmap.h" --#include "byte-order.h" --#include "openvswitch/compiler.h" --#include "openflow/nicira-ext.h" --#include "openflow/openflow.h" --#include "openvswitch/flow.h" --#include "packets.h" --#include "hash.h" --#include "util.h" -- --struct dpif_flow_stats; --struct dpif_flow_attrs; --struct ds; --struct flow_wildcards; --struct minimask; --struct dp_packet; --struct ofputil_port_map; --struct pkt_metadata; --struct match; -- --/* Some flow fields are mutually exclusive or only appear within the flow -- * pipeline. IPv6 headers are bigger than IPv4 and MPLS, and IPv6 ND packets -- * are bigger than TCP,UDP and IGMP packets. */ --#define FLOW_MAX_PACKET_U64S (FLOW_U64S \ -- /* Unused in datapath */ - FLOW_U64_SIZE(regs) \ -- - FLOW_U64_SIZE(metadata) \ -- /* L2.5/3 */ - FLOW_U64_SIZE(nw_src) /* incl. nw_dst */ \ -- - FLOW_U64_SIZE(mpls_lse) \ -- /* L4 */ - FLOW_U64_SIZE(tp_src) \ -- ) -- --extern const uint8_t flow_segment_u64s[]; -- --/* Configured maximum VLAN headers. */ --extern int flow_vlan_limit; -- --#define FLOW_U64_OFFSET(FIELD) \ -- (offsetof(struct flow, FIELD) / sizeof(uint64_t)) --#define FLOW_U64_OFFREM(FIELD) \ -- (offsetof(struct flow, FIELD) % sizeof(uint64_t)) -- --/* Number of 64-bit units spanned by a 'FIELD'. */ --#define FLOW_U64_SIZE(FIELD) \ -- DIV_ROUND_UP(FLOW_U64_OFFREM(FIELD) + MEMBER_SIZEOF(struct flow, FIELD), \ -- sizeof(uint64_t)) -- --void flow_extract(struct dp_packet *, struct flow *); -- --void flow_zero_wildcards(struct flow *, const struct flow_wildcards *); --void flow_unwildcard_tp_ports(const struct flow *, struct flow_wildcards *); --void flow_get_metadata(const struct flow *, struct match *flow_metadata); --struct netdev *flow_get_tunnel_netdev(struct flow_tnl *tunnel); -- --const char *ct_state_to_string(uint32_t state); --uint32_t ct_state_from_string(const char *); --bool parse_ct_state(const char *state_str, uint32_t default_state, -- uint32_t *ct_state, struct ds *); --bool validate_ct_state(uint32_t state, struct ds *); --void flow_clear_conntrack(struct flow *); -- --char *flow_to_string(const struct flow *, const struct ofputil_port_map *); --void format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t), -- uint32_t flags, char del); --void format_flags_masked(struct ds *ds, const char *name, -- const char *(*bit_to_string)(uint32_t), -- uint32_t flags, uint32_t mask, uint32_t max_mask); --void format_packet_type_masked(struct ds *, ovs_be32 value, ovs_be32 mask); --int parse_flags(const char *s, const char *(*bit_to_string)(uint32_t), -- char end, const char *field_name, char **res_string, -- uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask); -- --void flow_format(struct ds *, const struct flow *, -- const struct ofputil_port_map *); --void flow_print(FILE *, const struct flow *, const struct ofputil_port_map *); --static inline int flow_compare_3way(const struct flow *, const struct flow *); --static inline bool flow_equal(const struct flow *, const struct flow *); --static inline size_t flow_hash(const struct flow *, uint32_t basis); -- --void flow_set_dl_vlan(struct flow *, ovs_be16 vid, int id); --void flow_fix_vlan_tpid(struct flow *); --void flow_set_vlan_vid(struct flow *, ovs_be16 vid); --void flow_set_vlan_pcp(struct flow *, uint8_t pcp, int id); -- --void flow_limit_vlans(int vlan_limit); --int flow_count_vlan_headers(const struct flow *); --void flow_skip_common_vlan_headers(const struct flow *a, int *p_an, -- const struct flow *b, int *p_bn); --void flow_pop_vlan(struct flow*, struct flow_wildcards*); --void flow_push_vlan_uninit(struct flow*, struct flow_wildcards*); -- --int flow_count_mpls_labels(const struct flow *, struct flow_wildcards *); --int flow_count_common_mpls_labels(const struct flow *a, int an, -- const struct flow *b, int bn, -- struct flow_wildcards *wc); --void flow_push_mpls(struct flow *, int n, ovs_be16 mpls_eth_type, -- struct flow_wildcards *, bool clear_flow_L3); --bool flow_pop_mpls(struct flow *, int n, ovs_be16 eth_type, -- struct flow_wildcards *); --void flow_set_mpls_label(struct flow *, int idx, ovs_be32 label); --void flow_set_mpls_ttl(struct flow *, int idx, uint8_t ttl); --void flow_set_mpls_tc(struct flow *, int idx, uint8_t tc); --void flow_set_mpls_bos(struct flow *, int idx, uint8_t stack); --void flow_set_mpls_lse(struct flow *, int idx, ovs_be32 lse); -- --void flow_compose(struct dp_packet *, const struct flow *, -- const void *l7, size_t l7_len); --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); --bool parse_nsh(const void **datap, size_t *sizep, struct ovs_key_nsh *key); --uint16_t parse_tcp_flags(struct dp_packet *packet, ovs_be16 *dl_type_p, -- uint8_t *nw_frag_p, ovs_be16 *first_vlan_tci_p); -- --static inline uint64_t --flow_get_xreg(const struct flow *flow, int idx) --{ -- return ((uint64_t) flow->regs[idx * 2] << 32) | flow->regs[idx * 2 + 1]; --} -- --static inline void --flow_set_xreg(struct flow *flow, int idx, uint64_t value) --{ -- flow->regs[idx * 2] = value >> 32; -- flow->regs[idx * 2 + 1] = value; --} -- --static inline ovs_u128 --flow_get_xxreg(const struct flow *flow, int idx) --{ -- ovs_u128 value; -- -- value.u64.hi = (uint64_t) flow->regs[idx * 4] << 32; -- value.u64.hi |= flow->regs[idx * 4 + 1]; -- value.u64.lo = (uint64_t) flow->regs[idx * 4 + 2] << 32; -- value.u64.lo |= flow->regs[idx * 4 + 3]; -- -- return value; --} -- --static inline void --flow_set_xxreg(struct flow *flow, int idx, ovs_u128 value) --{ -- flow->regs[idx * 4] = value.u64.hi >> 32; -- flow->regs[idx * 4 + 1] = value.u64.hi; -- flow->regs[idx * 4 + 2] = value.u64.lo >> 32; -- flow->regs[idx * 4 + 3] = value.u64.lo; --} -- --static inline int --flow_compare_3way(const struct flow *a, const struct flow *b) --{ -- return memcmp(a, b, sizeof *a); --} -- --static inline bool --flow_equal(const struct flow *a, const struct flow *b) --{ -- return !flow_compare_3way(a, b); --} -- --static inline size_t --flow_hash(const struct flow *flow, uint32_t basis) --{ -- return hash_bytes64((const uint64_t *)flow, sizeof *flow, basis); --} -- --static inline uint16_t --ofp_to_u16(ofp_port_t ofp_port) --{ -- return (OVS_FORCE uint16_t) ofp_port; --} -- --static inline uint32_t --odp_to_u32(odp_port_t odp_port) --{ -- return (OVS_FORCE uint32_t) odp_port; --} -- --static inline uint32_t --ofp11_to_u32(ofp11_port_t ofp11_port) --{ -- return (OVS_FORCE uint32_t) ofp11_port; --} -- --static inline ofp_port_t --u16_to_ofp(uint16_t port) --{ -- return OFP_PORT_C(port); --} -- --static inline odp_port_t --u32_to_odp(uint32_t port) --{ -- return ODP_PORT_C(port); --} -- --static inline ofp11_port_t --u32_to_ofp11(uint32_t port) --{ -- return OFP11_PORT_C(port); --} -- --static inline uint32_t --hash_ofp_port(ofp_port_t ofp_port) --{ -- return hash_int(ofp_to_u16(ofp_port), 0); --} -- --static inline uint32_t --hash_odp_port(odp_port_t odp_port) --{ -- return hash_int(odp_to_u32(odp_port), 0); --} -- --uint32_t flow_hash_5tuple(const struct flow *flow, uint32_t basis); --uint32_t flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis); --uint32_t flow_hash_symmetric_l2(const struct flow *flow, uint32_t basis); --uint32_t flow_hash_symmetric_l3l4(const struct flow *flow, uint32_t basis, -- bool inc_udp_ports ); --uint32_t flow_hash_symmetric_l3(const struct flow *flow, uint32_t basis); -- --/* Initialize a flow with random fields that matter for nx_hash_fields. */ --void flow_random_hash_fields(struct flow *); --void flow_mask_hash_fields(const struct flow *, struct flow_wildcards *, -- enum nx_hash_fields); --uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields, -- uint16_t basis); --const char *flow_hash_fields_to_str(enum nx_hash_fields); --bool flow_hash_fields_valid(enum nx_hash_fields); -- --uint32_t flow_hash_in_wildcards(const struct flow *, -- const struct flow_wildcards *, -- uint32_t basis); -- --bool flow_equal_except(const struct flow *a, const struct flow *b, -- const struct flow_wildcards *); -- --/* Bitmap for flow values. For each 1-bit the corresponding flow value is -- * explicitly specified, other values are zeroes. -- * -- * map_t must be wide enough to hold any member of struct flow. */ --typedef unsigned long long map_t; --#define MAP_T_BITS (sizeof(map_t) * CHAR_BIT) --#define MAP_1 (map_t)1 --#define MAP_MAX TYPE_MAXIMUM(map_t) -- --#define MAP_IS_SET(MAP, IDX) ((MAP) & (MAP_1 << (IDX))) -- --/* Iterate through the indices of all 1-bits in 'MAP'. */ --#define MAP_FOR_EACH_INDEX(IDX, MAP) \ -- ULLONG_FOR_EACH_1(IDX, MAP) -- --#define FLOWMAP_UNITS DIV_ROUND_UP(FLOW_U64S, MAP_T_BITS) -- --struct flowmap { -- map_t bits[FLOWMAP_UNITS]; --}; -- --#define FLOWMAP_EMPTY_INITIALIZER { { 0 } } -- --static inline void flowmap_init(struct flowmap *); --static inline bool flowmap_equal(struct flowmap, struct flowmap); --static inline bool flowmap_is_set(const struct flowmap *, size_t idx); --static inline bool flowmap_are_set(const struct flowmap *, size_t idx, -- unsigned int n_bits); --static inline void flowmap_set(struct flowmap *, size_t idx, -- unsigned int n_bits); --static inline void flowmap_clear(struct flowmap *, size_t idx, -- unsigned int n_bits); --static inline struct flowmap flowmap_or(struct flowmap, struct flowmap); --static inline struct flowmap flowmap_and(struct flowmap, struct flowmap); --static inline bool flowmap_is_empty(struct flowmap); --static inline unsigned int flowmap_n_1bits(struct flowmap); -- --#define FLOWMAP_HAS_FIELD(FM, FIELD) \ -- flowmap_are_set(FM, FLOW_U64_OFFSET(FIELD), FLOW_U64_SIZE(FIELD)) -- --#define FLOWMAP_SET(FM, FIELD) \ -- flowmap_set(FM, FLOW_U64_OFFSET(FIELD), FLOW_U64_SIZE(FIELD)) -- --#define FLOWMAP_SET__(FM, FIELD, SIZE) \ -- flowmap_set(FM, FLOW_U64_OFFSET(FIELD), \ -- DIV_ROUND_UP(SIZE, sizeof(uint64_t))) -- --/* XXX: Only works for full 64-bit units. */ --#define FLOWMAP_CLEAR(FM, FIELD) \ -- BUILD_ASSERT_DECL(FLOW_U64_OFFREM(FIELD) == 0); \ -- BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->FIELD) % sizeof(uint64_t) == 0); \ -- flowmap_clear(FM, FLOW_U64_OFFSET(FIELD), FLOW_U64_SIZE(FIELD)) -- --/* Iterate through all units in 'FMAP'. */ --#define FLOWMAP_FOR_EACH_UNIT(UNIT) \ -- for ((UNIT) = 0; (UNIT) < FLOWMAP_UNITS; (UNIT)++) -- --/* Iterate through all map units in 'FMAP'. */ --#define FLOWMAP_FOR_EACH_MAP(MAP, FLOWMAP) \ -- for (size_t unit__ = 0; \ -- unit__ < FLOWMAP_UNITS && ((MAP) = (FLOWMAP).bits[unit__], true); \ -- unit__++) -- --struct flowmap_aux; --static inline bool flowmap_next_index(struct flowmap_aux *, size_t *idx); -- --#define FLOWMAP_AUX_INITIALIZER(FLOWMAP) { .unit = 0, .map = (FLOWMAP) } -- --/* Iterate through all struct flow u64 indices specified by 'MAP'. This is a -- * slower but easier version of the FLOWMAP_FOR_EACH_MAP() & -- * MAP_FOR_EACH_INDEX() combination. */ --#define FLOWMAP_FOR_EACH_INDEX(IDX, MAP) \ -- for (struct flowmap_aux aux__ = FLOWMAP_AUX_INITIALIZER(MAP); \ -- flowmap_next_index(&aux__, &(IDX));) -- --/* Flowmap inline implementations. */ --static inline void --flowmap_init(struct flowmap *fm) --{ -- memset(fm, 0, sizeof *fm); --} -- --static inline bool --flowmap_equal(struct flowmap a, struct flowmap b) --{ -- return !memcmp(&a, &b, sizeof a); --} -- --static inline bool --flowmap_is_set(const struct flowmap *fm, size_t idx) --{ -- return (fm->bits[idx / MAP_T_BITS] & (MAP_1 << (idx % MAP_T_BITS))) != 0; --} -- --/* Returns 'true' if any of the 'n_bits' bits starting at 'idx' are set in -- * 'fm'. 'n_bits' can be at most MAP_T_BITS. */ --static inline bool --flowmap_are_set(const struct flowmap *fm, size_t idx, unsigned int n_bits) --{ -- map_t n_bits_mask = (MAP_1 << n_bits) - 1; -- size_t unit = idx / MAP_T_BITS; -- -- idx %= MAP_T_BITS; -- -- if (fm->bits[unit] & (n_bits_mask << idx)) { -- return true; -- } -- /* The seemingly unnecessary bounds check on 'unit' is a workaround for a -- * false-positive array out of bounds error by GCC 4.9. */ -- if (unit + 1 < FLOWMAP_UNITS && idx + n_bits > MAP_T_BITS) { -- /* Check the remaining bits from the next unit. */ -- return fm->bits[unit + 1] & (n_bits_mask >> (MAP_T_BITS - idx)); -- } -- return false; --} -- --/* Set the 'n_bits' consecutive bits in 'fm', starting at bit 'idx'. -- * 'n_bits' can be at most MAP_T_BITS. */ --static inline void --flowmap_set(struct flowmap *fm, size_t idx, unsigned int n_bits) --{ -- map_t n_bits_mask = (MAP_1 << n_bits) - 1; -- size_t unit = idx / MAP_T_BITS; -- -- idx %= MAP_T_BITS; -- -- fm->bits[unit] |= n_bits_mask << idx; -- /* The seemingly unnecessary bounds check on 'unit' is a workaround for a -- * false-positive array out of bounds error by GCC 4.9. */ -- if (unit + 1 < FLOWMAP_UNITS && idx + n_bits > MAP_T_BITS) { -- /* 'MAP_T_BITS - idx' bits were set on 'unit', set the remaining -- * bits from the next unit. */ -- fm->bits[unit + 1] |= n_bits_mask >> (MAP_T_BITS - idx); -- } --} -- --/* Clears the 'n_bits' consecutive bits in 'fm', starting at bit 'idx'. -- * 'n_bits' can be at most MAP_T_BITS. */ --static inline void --flowmap_clear(struct flowmap *fm, size_t idx, unsigned int n_bits) --{ -- map_t n_bits_mask = (MAP_1 << n_bits) - 1; -- size_t unit = idx / MAP_T_BITS; -- -- idx %= MAP_T_BITS; -- -- fm->bits[unit] &= ~(n_bits_mask << idx); -- /* The seemingly unnecessary bounds check on 'unit' is a workaround for a -- * false-positive array out of bounds error by GCC 4.9. */ -- if (unit + 1 < FLOWMAP_UNITS && idx + n_bits > MAP_T_BITS) { -- /* 'MAP_T_BITS - idx' bits were cleared on 'unit', clear the -- * remaining bits from the next unit. */ -- fm->bits[unit + 1] &= ~(n_bits_mask >> (MAP_T_BITS - idx)); -- } --} -- --/* OR the bits in the flowmaps. */ --static inline struct flowmap --flowmap_or(struct flowmap a, struct flowmap b) --{ -- struct flowmap map; -- size_t unit; -- -- FLOWMAP_FOR_EACH_UNIT (unit) { -- map.bits[unit] = a.bits[unit] | b.bits[unit]; -- } -- return map; --} -- --/* AND the bits in the flowmaps. */ --static inline struct flowmap --flowmap_and(struct flowmap a, struct flowmap b) --{ -- struct flowmap map; -- size_t unit; -- -- FLOWMAP_FOR_EACH_UNIT (unit) { -- map.bits[unit] = a.bits[unit] & b.bits[unit]; -- } -- return map; --} -- --static inline bool --flowmap_is_empty(struct flowmap fm) --{ -- map_t map; -- -- FLOWMAP_FOR_EACH_MAP (map, fm) { -- if (map) { -- return false; -- } -- } -- return true; --} -- --static inline unsigned int --flowmap_n_1bits(struct flowmap fm) --{ -- unsigned int n_1bits = 0; -- size_t unit; -- -- FLOWMAP_FOR_EACH_UNIT (unit) { -- n_1bits += count_1bits(fm.bits[unit]); -- } -- return n_1bits; --} -- --struct flowmap_aux { -- size_t unit; -- struct flowmap map; --}; -- --static inline bool --flowmap_next_index(struct flowmap_aux *aux, size_t *idx) --{ -- for (;;) { -- map_t *map = &aux->map.bits[aux->unit]; -- if (*map) { -- *idx = aux->unit * MAP_T_BITS + raw_ctz(*map); -- *map = zero_rightmost_1bit(*map); -- return true; -- } -- if (++aux->unit >= FLOWMAP_UNITS) { -- return false; -- } -- } --} -- -- --/* Compressed flow. */ -- --/* A sparse representation of a "struct flow". -- * -- * A "struct flow" is fairly large and tends to be mostly zeros. Sparse -- * representation has two advantages. First, it saves memory and, more -- * importantly, minimizes the number of accessed cache lines. Second, it saves -- * time when the goal is to iterate over only the nonzero parts of the struct. -- * -- * The map member hold one bit for each uint64_t in a "struct flow". Each -- * 0-bit indicates that the corresponding uint64_t is zero, each 1-bit that it -- * *may* be nonzero (see below how this applies to minimasks). -- * -- * The values indicated by 'map' always follow the miniflow in memory. The -- * user of the miniflow is responsible for always having enough storage after -- * the struct miniflow corresponding to the number of 1-bits in maps. -- * -- * Elements in values array are allowed to be zero. This is useful for "struct -- * minimatch", for which ensuring that the miniflow and minimask members have -- * same maps allows optimization. This allowance applies only to a miniflow -- * that is not a mask. That is, a minimask may NOT have zero elements in its -- * values. -- * -- * A miniflow is always dynamically allocated so that the maps are followed by -- * at least as many elements as there are 1-bits in maps. */ --struct miniflow { -- struct flowmap map; -- /* Followed by: -- * uint64_t values[n]; -- * where 'n' is miniflow_n_values(miniflow). */ --}; --BUILD_ASSERT_DECL(sizeof(struct miniflow) % sizeof(uint64_t) == 0); -- --#define MINIFLOW_VALUES_SIZE(COUNT) ((COUNT) * sizeof(uint64_t)) -- --static inline uint64_t *miniflow_values(struct miniflow *mf) --{ -- return (uint64_t *)(mf + 1); --} -- --static inline const uint64_t *miniflow_get_values(const struct miniflow *mf) --{ -- return (const uint64_t *)(mf + 1); --} -- --struct pkt_metadata; -- --/* The 'dst' must follow with buffer space for FLOW_U64S 64-bit units. -- * 'dst->map' is ignored on input and set on output to indicate which fields -- * were extracted. */ --void miniflow_extract(struct dp_packet *packet, struct miniflow *dst); --void miniflow_map_init(struct miniflow *, const struct flow *); --void flow_wc_map(const struct flow *, struct flowmap *); --size_t miniflow_alloc(struct miniflow *dsts[], size_t n, -- const struct miniflow *src); --void miniflow_init(struct miniflow *, const struct flow *); --void miniflow_clone(struct miniflow *, const struct miniflow *, -- size_t n_values); --struct miniflow * miniflow_create(const struct flow *); -- --void miniflow_expand(const struct miniflow *, struct flow *); -- --static inline uint64_t flow_u64_value(const struct flow *flow, size_t index) --{ -- return ((uint64_t *)flow)[index]; --} -- --static inline uint64_t *flow_u64_lvalue(struct flow *flow, size_t index) --{ -- return &((uint64_t *)flow)[index]; --} -- --static inline size_t --miniflow_n_values(const struct miniflow *flow) --{ -- return flowmap_n_1bits(flow->map); --} -- --struct flow_for_each_in_maps_aux { -- const struct flow *flow; -- struct flowmap_aux map_aux; --}; -- --static inline bool --flow_values_get_next_in_maps(struct flow_for_each_in_maps_aux *aux, -- uint64_t *value) --{ -- size_t idx; -- -- if (flowmap_next_index(&aux->map_aux, &idx)) { -- *value = flow_u64_value(aux->flow, idx); -- return true; -- } -- return false; --} -- --/* Iterate through all flow u64 values specified by 'MAPS'. */ --#define FLOW_FOR_EACH_IN_MAPS(VALUE, FLOW, MAPS) \ -- for (struct flow_for_each_in_maps_aux aux__ \ -- = { (FLOW), FLOWMAP_AUX_INITIALIZER(MAPS) }; \ -- flow_values_get_next_in_maps(&aux__, &(VALUE));) -- --struct mf_for_each_in_map_aux { -- size_t unit; /* Current 64-bit unit of the flowmaps -- being processed. */ -- struct flowmap fmap; /* Remaining 1-bits corresponding to the -- 64-bit words in 'values' */ -- struct flowmap map; /* Remaining 1-bits corresponding to the -- 64-bit words of interest. */ -- const uint64_t *values; /* 64-bit words corresponding to the -- 1-bits in 'fmap'. */ --}; -- --/* Get the data from 'aux->values' corresponding to the next lowest 1-bit -- * in 'aux->map', given that 'aux->values' points to an array of 64-bit -- * words corresponding to the 1-bits in 'aux->fmap', starting from the -- * rightmost 1-bit. -- * -- * Returns 'true' if the traversal is incomplete, 'false' otherwise. -- * 'aux' is prepared for the next iteration after each call. -- * -- * This is used to traverse through, for example, the values in a miniflow -- * representation of a flow key selected by non-zero 64-bit words in a -- * corresponding subtable mask. */ --static inline bool --mf_get_next_in_map(struct mf_for_each_in_map_aux *aux, -- uint64_t *value) --{ -- map_t *map, *fmap; -- map_t rm1bit; -- -- /* Skip empty map units. */ -- while (OVS_UNLIKELY(!*(map = &aux->map.bits[aux->unit]))) { -- /* Skip remaining data in the current unit before advancing -- * to the next. */ -- aux->values += count_1bits(aux->fmap.bits[aux->unit]); -- if (++aux->unit == FLOWMAP_UNITS) { -- return false; -- } -- } -- -- rm1bit = rightmost_1bit(*map); -- *map -= rm1bit; -- fmap = &aux->fmap.bits[aux->unit]; -- -- /* If the rightmost 1-bit found from the current unit in 'aux->map' -- * ('rm1bit') is also present in 'aux->fmap', store the corresponding -- * value from 'aux->values' to '*value', otherwise store 0. */ -- if (OVS_LIKELY(*fmap & rm1bit)) { -- /* Skip all 64-bit words in 'values' preceding the one corresponding -- * to 'rm1bit'. */ -- map_t trash = *fmap & (rm1bit - 1); -- -- /* Avoid resetting 'fmap' and calling count_1bits() when trash is -- * zero. */ -- if (trash) { -- *fmap -= trash; -- aux->values += count_1bits(trash); -- } -- -- *value = *aux->values; -- } else { -- *value = 0; -- } -- return true; --} -- --/* Iterate through miniflow u64 values specified by 'FLOWMAP'. */ --#define MINIFLOW_FOR_EACH_IN_FLOWMAP(VALUE, FLOW, FLOWMAP) \ -- for (struct mf_for_each_in_map_aux aux__ = \ -- { 0, (FLOW)->map, (FLOWMAP), miniflow_get_values(FLOW) }; \ -- mf_get_next_in_map(&aux__, &(VALUE));) -- --/* This can be used when it is known that 'idx' is set in 'map'. */ --static inline const uint64_t * --miniflow_values_get__(const uint64_t *values, map_t map, size_t idx) --{ -- return values + count_1bits(map & ((MAP_1 << idx) - 1)); --} -- --/* This can be used when it is known that 'u64_idx' is set in -- * the map of 'mf'. */ --static inline const uint64_t * --miniflow_get__(const struct miniflow *mf, size_t idx) --{ -- const uint64_t *values = miniflow_get_values(mf); -- const map_t *map = mf->map.bits; -- -- while (idx >= MAP_T_BITS) { -- idx -= MAP_T_BITS; -- values += count_1bits(*map++); -- } -- return miniflow_values_get__(values, *map, idx); --} -- --#define MINIFLOW_IN_MAP(MF, IDX) flowmap_is_set(&(MF)->map, IDX) -- --/* Get the value of the struct flow 'FIELD' as up to 8 byte wide integer type -- * 'TYPE' from miniflow 'MF'. */ --#define MINIFLOW_GET_TYPE(MF, TYPE, FIELD) \ -- (BUILD_ASSERT(sizeof(TYPE) == sizeof(((struct flow *)0)->FIELD)), \ -- BUILD_ASSERT_GCCONLY(__builtin_types_compatible_p(TYPE, typeof(((struct flow *)0)->FIELD))), \ -- MINIFLOW_GET_TYPE__(MF, TYPE, FIELD)) -- --/* Like MINIFLOW_GET_TYPE, but without checking that TYPE is the correct width -- * for FIELD. (This is useful for deliberately reading adjacent fields in one -- * go.) */ --#define MINIFLOW_GET_TYPE__(MF, TYPE, FIELD) \ -- (MINIFLOW_IN_MAP(MF, FLOW_U64_OFFSET(FIELD)) \ -- ? ((OVS_FORCE const TYPE *)miniflow_get__(MF, FLOW_U64_OFFSET(FIELD))) \ -- [FLOW_U64_OFFREM(FIELD) / sizeof(TYPE)] \ -- : 0) -- --#define MINIFLOW_GET_U128(FLOW, FIELD) \ -- (ovs_u128) { .u64 = { \ -- (MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD)) ? \ -- *miniflow_get__(FLOW, FLOW_U64_OFFSET(FIELD)) : 0), \ -- (MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD) + 1) ? \ -- *miniflow_get__(FLOW, FLOW_U64_OFFSET(FIELD) + 1) : 0) } } -- --#define MINIFLOW_GET_U8(FLOW, FIELD) \ -- MINIFLOW_GET_TYPE(FLOW, uint8_t, FIELD) --#define MINIFLOW_GET_U16(FLOW, FIELD) \ -- MINIFLOW_GET_TYPE(FLOW, uint16_t, FIELD) --#define MINIFLOW_GET_BE16(FLOW, FIELD) \ -- MINIFLOW_GET_TYPE(FLOW, ovs_be16, FIELD) --#define MINIFLOW_GET_U32(FLOW, FIELD) \ -- MINIFLOW_GET_TYPE(FLOW, uint32_t, FIELD) --#define MINIFLOW_GET_BE32(FLOW, FIELD) \ -- MINIFLOW_GET_TYPE(FLOW, ovs_be32, FIELD) --#define MINIFLOW_GET_U64(FLOW, FIELD) \ -- MINIFLOW_GET_TYPE(FLOW, uint64_t, FIELD) --#define MINIFLOW_GET_BE64(FLOW, FIELD) \ -- MINIFLOW_GET_TYPE(FLOW, ovs_be64, FIELD) -- --static inline uint64_t miniflow_get(const struct miniflow *, -- unsigned int u64_ofs); --static inline uint32_t miniflow_get_u32(const struct miniflow *, -- unsigned int u32_ofs); --static inline ovs_be32 miniflow_get_be32(const struct miniflow *, -- unsigned int be32_ofs); --static inline uint16_t miniflow_get_vid(const struct miniflow *, size_t); --static inline uint16_t miniflow_get_tcp_flags(const struct miniflow *); --static inline ovs_be64 miniflow_get_metadata(const struct miniflow *); --static inline uint64_t miniflow_get_tun_metadata_present_map( -- const struct miniflow *); --static inline uint32_t miniflow_get_recirc_id(const struct miniflow *); --static inline uint32_t miniflow_get_dp_hash(const struct miniflow *); --static inline ovs_be32 miniflow_get_ports(const struct miniflow *); -- --bool miniflow_equal(const struct miniflow *a, const struct miniflow *b); --bool miniflow_equal_in_minimask(const struct miniflow *a, -- const struct miniflow *b, -- const struct minimask *); --bool miniflow_equal_flow_in_minimask(const struct miniflow *a, -- const struct flow *b, -- const struct minimask *); --uint32_t miniflow_hash_5tuple(const struct miniflow *flow, uint32_t basis); -- -- --/* Compressed flow wildcards. */ -- --/* A sparse representation of a "struct flow_wildcards". -- * -- * See the large comment on struct miniflow for details. -- * -- * Note: While miniflow can have zero data for a 1-bit in the map, -- * a minimask may not! We rely on this in the implementation. */ --struct minimask { -- struct miniflow masks; --}; -- --void minimask_init(struct minimask *, const struct flow_wildcards *); --struct minimask * minimask_create(const struct flow_wildcards *); --void minimask_combine(struct minimask *dst, -- const struct minimask *a, const struct minimask *b, -- uint64_t storage[FLOW_U64S]); -- --void minimask_expand(const struct minimask *, struct flow_wildcards *); -- --static inline uint32_t minimask_get_u32(const struct minimask *, -- unsigned int u32_ofs); --static inline ovs_be32 minimask_get_be32(const struct minimask *, -- unsigned int be32_ofs); --static inline uint16_t minimask_get_vid_mask(const struct minimask *, size_t); --static inline ovs_be64 minimask_get_metadata_mask(const struct minimask *); -- --bool minimask_equal(const struct minimask *a, const struct minimask *b); --bool minimask_has_extra(const struct minimask *, const struct minimask *); -- -- --/* Returns true if 'mask' matches every packet, false if 'mask' fixes any bits -- * or fields. */ --static inline bool --minimask_is_catchall(const struct minimask *mask) --{ -- /* For every 1-bit in mask's map, the corresponding value is non-zero, -- * so the only way the mask can not fix any bits or fields is for the -- * map the be zero. */ -- return flowmap_is_empty(mask->masks.map); --} -- --/* Returns the uint64_t that would be at byte offset '8 * u64_ofs' if 'flow' -- * were expanded into a "struct flow". */ --static inline uint64_t miniflow_get(const struct miniflow *flow, -- unsigned int u64_ofs) --{ -- return MINIFLOW_IN_MAP(flow, u64_ofs) ? *miniflow_get__(flow, u64_ofs) : 0; --} -- --static inline uint32_t miniflow_get_u32(const struct miniflow *flow, -- unsigned int u32_ofs) --{ -- uint64_t value = miniflow_get(flow, u32_ofs / 2); -- --#if WORDS_BIGENDIAN -- return (u32_ofs & 1) ? value : value >> 32; --#else -- return (u32_ofs & 1) ? value >> 32 : value; --#endif --} -- --static inline ovs_be32 miniflow_get_be32(const struct miniflow *flow, -- unsigned int be32_ofs) --{ -- return (OVS_FORCE ovs_be32)miniflow_get_u32(flow, be32_ofs); --} -- --/* Returns the VID within the vlan_tci member of the "struct flow" represented -- * by 'flow'. */ --static inline uint16_t --miniflow_get_vid(const struct miniflow *flow, size_t n) --{ -- if (n < FLOW_MAX_VLAN_HEADERS) { -- union flow_vlan_hdr hdr = { -- .qtag = MINIFLOW_GET_BE32(flow, vlans[n].qtag) -- }; -- return vlan_tci_to_vid(hdr.tci); -- } -- return 0; --} -- --/* Returns the uint32_t that would be at byte offset '4 * u32_ofs' if 'mask' -- * were expanded into a "struct flow_wildcards". */ --static inline uint32_t --minimask_get_u32(const struct minimask *mask, unsigned int u32_ofs) --{ -- return miniflow_get_u32(&mask->masks, u32_ofs); --} -- --static inline ovs_be32 --minimask_get_be32(const struct minimask *mask, unsigned int be32_ofs) --{ -- return (OVS_FORCE ovs_be32)minimask_get_u32(mask, be32_ofs); --} -- --/* Returns the VID mask within the vlan_tci member of the "struct -- * flow_wildcards" represented by 'mask'. */ --static inline uint16_t --minimask_get_vid_mask(const struct minimask *mask, size_t n) --{ -- return miniflow_get_vid(&mask->masks, n); --} -- --/* Returns the value of the "tcp_flags" field in 'flow'. */ --static inline uint16_t --miniflow_get_tcp_flags(const struct miniflow *flow) --{ -- return ntohs(MINIFLOW_GET_BE16(flow, tcp_flags)); --} -- --/* Returns the value of the OpenFlow 1.1+ "metadata" field in 'flow'. */ --static inline ovs_be64 --miniflow_get_metadata(const struct miniflow *flow) --{ -- return MINIFLOW_GET_BE64(flow, metadata); --} -- --/* Returns the bitmap that indicates which tunnel metadata fields are present -- * in 'flow'. */ --static inline uint64_t --miniflow_get_tun_metadata_present_map(const struct miniflow *flow) --{ -- return MINIFLOW_GET_U64(flow, tunnel.metadata.present.map); --} -- --/* Returns the recirc_id in 'flow.' */ --static inline uint32_t --miniflow_get_recirc_id(const struct miniflow *flow) --{ -- return MINIFLOW_GET_U32(flow, recirc_id); --} -- --/* Returns the dp_hash in 'flow.' */ --static inline uint32_t --miniflow_get_dp_hash(const struct miniflow *flow) --{ -- return MINIFLOW_GET_U32(flow, dp_hash); --} -- --/* Returns the 'tp_src' and 'tp_dst' fields together as one piece of data. */ --static inline ovs_be32 --miniflow_get_ports(const struct miniflow *flow) --{ -- return MINIFLOW_GET_TYPE__(flow, ovs_be32, tp_src); --} -- --/* Returns the mask for the OpenFlow 1.1+ "metadata" field in 'mask'. -- * -- * The return value is all-1-bits if 'mask' matches on the whole value of the -- * metadata field, all-0-bits if 'mask' entirely wildcards the metadata field, -- * or some other value if the metadata field is partially matched, partially -- * wildcarded. */ --static inline ovs_be64 --minimask_get_metadata_mask(const struct minimask *mask) --{ -- return MINIFLOW_GET_BE64(&mask->masks, metadata); --} -- --/* Perform a bitwise OR of miniflow 'src' flow data specified in 'subset' with -- * the equivalent fields in 'dst', storing the result in 'dst'. 'subset' must -- * be a subset of 'src's map. */ --static inline void --flow_union_with_miniflow_subset(struct flow *dst, const struct miniflow *src, -- struct flowmap subset) --{ -- uint64_t *dst_u64 = (uint64_t *) dst; -- const uint64_t *p = miniflow_get_values(src); -- map_t map; -- -- FLOWMAP_FOR_EACH_MAP (map, subset) { -- size_t idx; -- -- MAP_FOR_EACH_INDEX(idx, map) { -- dst_u64[idx] |= *p++; -- } -- dst_u64 += MAP_T_BITS; -- } --} -- --/* Perform a bitwise OR of miniflow 'src' flow data with the equivalent -- * fields in 'dst', storing the result in 'dst'. */ --static inline void --flow_union_with_miniflow(struct flow *dst, const struct miniflow *src) --{ -- flow_union_with_miniflow_subset(dst, src, src->map); --} -- --static inline bool is_ct_valid(const struct flow *flow, -- const struct flow_wildcards *mask, -- struct flow_wildcards *wc) --{ -- /* Matches are checked with 'mask' and without 'wc'. */ -- if (mask && !wc) { -- /* Must match at least one of the bits that implies a valid -- * conntrack entry, or an explicit not-invalid. */ -- return flow->ct_state & (CS_NEW | CS_ESTABLISHED | CS_RELATED -- | CS_REPLY_DIR | CS_SRC_NAT | CS_DST_NAT) -- || (flow->ct_state & CS_TRACKED -- && mask->masks.ct_state & CS_INVALID -- && !(flow->ct_state & CS_INVALID)); -- } -- /* Else we are checking a fully extracted flow, where valid CT state always -- * has either 'new', 'established', or 'reply_dir' bit set. */ --#define CS_VALID_MASK (CS_NEW | CS_ESTABLISHED | CS_REPLY_DIR) -- if (wc) { -- wc->masks.ct_state |= CS_VALID_MASK; -- } -- return flow->ct_state & CS_VALID_MASK; --} -- --static inline void --pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow) --{ -- /* Update this function whenever struct flow changes. */ -- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42); -- -- md->recirc_id = flow->recirc_id; -- md->dp_hash = flow->dp_hash; -- flow_tnl_copy__(&md->tunnel, &flow->tunnel); -- md->skb_priority = flow->skb_priority; -- md->pkt_mark = flow->pkt_mark; -- md->in_port = flow->in_port; -- md->ct_state = flow->ct_state; -- md->ct_zone = flow->ct_zone; -- md->ct_mark = flow->ct_mark; -- md->ct_label = flow->ct_label; -- -- md->ct_orig_tuple_ipv6 = false; -- if (flow->dl_type && is_ct_valid(flow, NULL, NULL)) { -- if (flow->dl_type == htons(ETH_TYPE_IP)) { -- md->ct_orig_tuple.ipv4 = (struct ovs_key_ct_tuple_ipv4) { -- flow->ct_nw_src, -- flow->ct_nw_dst, -- flow->ct_tp_src, -- flow->ct_tp_dst, -- flow->ct_nw_proto, -- }; -- } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) { -- md->ct_orig_tuple_ipv6 = true; -- md->ct_orig_tuple.ipv6 = (struct ovs_key_ct_tuple_ipv6) { -- flow->ct_ipv6_src, -- flow->ct_ipv6_dst, -- flow->ct_tp_src, -- flow->ct_tp_dst, -- flow->ct_nw_proto, -- }; -- } else { -- /* Reset ct_orig_tuple for other types. */ -- memset(&md->ct_orig_tuple, 0, sizeof md->ct_orig_tuple); -- } -- } else { -- memset(&md->ct_orig_tuple, 0, sizeof md->ct_orig_tuple); -- } --} -- --/* Often, during translation we need to read a value from a flow('FLOW') and -- * unwildcard the corresponding bits in the wildcards('WC'). This macro makes -- * it easier to do that. */ -- --#define FLOW_WC_GET_AND_MASK_WC(FLOW, WC, FIELD) \ -- (((WC) ? WC_MASK_FIELD(WC, FIELD) : NULL), ((FLOW)->FIELD)) -- --static inline bool is_ethernet(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (wc) { -- WC_MASK_FIELD(wc, packet_type); -- } -- return flow->packet_type == htonl(PT_ETH); --} -- --static inline ovs_be16 get_dl_type(const struct flow *flow) --{ -- if (flow->packet_type == htonl(PT_ETH)) { -- return flow->dl_type; -- } else if (pt_ns(flow->packet_type) == OFPHTN_ETHERTYPE) { -- return pt_ns_type_be(flow->packet_type); -- } else { -- return htons(FLOW_DL_TYPE_NONE); -- } --} -- --static inline bool is_vlan(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (!is_ethernet(flow, wc)) { -- return false; -- } -- if (wc) { -- WC_MASK_FIELD_MASK(wc, vlans[0].tci, htons(VLAN_CFI)); -- } -- return (flow->vlans[0].tci & htons(VLAN_CFI)) != 0; --} -- --static inline bool is_ip_any(const struct flow *flow) --{ -- return dl_type_is_ip_any(get_dl_type(flow)); --} -- --static inline bool is_ip_proto(const struct flow *flow, uint8_t ip_proto, -- struct flow_wildcards *wc) --{ -- if (is_ip_any(flow)) { -- if (wc) { -- WC_MASK_FIELD(wc, nw_proto); -- } -- return flow->nw_proto == ip_proto; -- } -- return false; --} -- --static inline bool is_tcp(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- return is_ip_proto(flow, IPPROTO_TCP, wc); --} -- --static inline bool is_udp(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- return is_ip_proto(flow, IPPROTO_UDP, wc); --} -- --static inline bool is_sctp(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- return is_ip_proto(flow, IPPROTO_SCTP, wc); --} -- --static inline bool is_icmpv4(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (get_dl_type(flow) == htons(ETH_TYPE_IP)) { -- if (wc) { -- memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); -- } -- return flow->nw_proto == IPPROTO_ICMP; -- } -- return false; --} -- --static inline bool is_icmpv6(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (get_dl_type(flow) == htons(ETH_TYPE_IPV6)) { -- if (wc) { -- memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); -- } -- return flow->nw_proto == IPPROTO_ICMPV6; -- } -- return false; --} -- --static inline bool is_nd(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (is_icmpv6(flow, wc)) { -- if (wc) { -- memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst); -- } -- if (flow->tp_dst != htons(0)) { -- return false; -- } -- -- if (wc) { -- memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); -- } -- return (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || -- flow->tp_src == htons(ND_NEIGHBOR_ADVERT)); -- } -- return false; --} -- --static inline bool is_arp(const struct flow *flow) --{ -- return (flow->dl_type == htons(ETH_TYPE_ARP)); --} -- --static inline bool is_garp(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (is_arp(flow)) { -- return (FLOW_WC_GET_AND_MASK_WC(flow, wc, nw_src) == -- FLOW_WC_GET_AND_MASK_WC(flow, wc, nw_dst)); -- } -- -- return false; --} -- --static inline bool is_igmp(const struct flow *flow, struct flow_wildcards *wc) --{ -- if (get_dl_type(flow) == htons(ETH_TYPE_IP)) { -- if (wc) { -- memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); -- } -- return flow->nw_proto == IPPROTO_IGMP; -- } -- return false; --} -- --static inline bool is_mld(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (is_icmpv6(flow, wc)) { -- if (wc) { -- memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); -- } -- return (flow->tp_src == htons(MLD_QUERY) -- || flow->tp_src == htons(MLD_REPORT) -- || flow->tp_src == htons(MLD_DONE) -- || flow->tp_src == htons(MLD2_REPORT)); -- } -- return false; --} -- --static inline bool is_mld_query(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- if (is_icmpv6(flow, wc)) { -- if (wc) { -- memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); -- } -- return flow->tp_src == htons(MLD_QUERY); -- } -- return false; --} -- --static inline bool is_mld_report(const struct flow *flow, -- struct flow_wildcards *wc) --{ -- return is_mld(flow, wc) && !is_mld_query(flow, wc); --} -- --static inline bool is_stp(const struct flow *flow) --{ -- return (flow->dl_type == htons(FLOW_DL_TYPE_NONE) -- && eth_addr_equals(flow->dl_dst, eth_addr_stp)); --} -- --/* Returns true if flow->tp_dst equals 'port'. If 'wc' is nonnull, sets -- * appropriate bits in wc->masks.tp_dst to account for the test. -- * -- * The caller must already have ensured that 'flow' is a protocol for which -- * tp_dst is relevant. */ --static inline bool tp_dst_equals(const struct flow *flow, uint16_t port, -- struct flow_wildcards *wc) --{ -- uint16_t diff = port ^ ntohs(flow->tp_dst); -- if (wc) { -- if (diff) { -- /* Set mask for the most significant mismatching bit. */ -- int ofs = raw_clz64((uint64_t) diff << 48); /* range [0,15] */ -- wc->masks.tp_dst |= htons(0x8000 >> ofs); -- } else { -- /* Must match all bits. */ -- wc->masks.tp_dst = OVS_BE16_MAX; -- } -- } -- return !diff; --} -- --#endif /* flow.h */ -Index: openvswitch-2.17.2/include/internal/flow.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/flow.h -@@ -0,0 +1,1215 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+#ifndef FLOW_H -+#define FLOW_H 1 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "internal/bitmap.h" -+#include "internal/byte-order.h" -+#include "openvswitch/compiler.h" -+#include "openflow/nicira-ext.h" -+#include "openflow/openflow.h" -+#include "openvswitch/flow.h" -+#include "internal/packets.h" -+#include "internal/hash.h" -+#include "internal/util.h" -+ -+struct dpif_flow_stats; -+struct dpif_flow_attrs; -+struct ds; -+struct flow_wildcards; -+struct minimask; -+struct dp_packet; -+struct ofputil_port_map; -+struct pkt_metadata; -+struct match; -+ -+/* Some flow fields are mutually exclusive or only appear within the flow -+ * pipeline. IPv6 headers are bigger than IPv4 and MPLS, and IPv6 ND packets -+ * are bigger than TCP,UDP and IGMP packets. */ -+#define FLOW_MAX_PACKET_U64S (FLOW_U64S \ -+ /* Unused in datapath */ - FLOW_U64_SIZE(regs) \ -+ - FLOW_U64_SIZE(metadata) \ -+ /* L2.5/3 */ - FLOW_U64_SIZE(nw_src) /* incl. nw_dst */ \ -+ - FLOW_U64_SIZE(mpls_lse) \ -+ /* L4 */ - FLOW_U64_SIZE(tp_src) \ -+ ) -+ -+extern const uint8_t flow_segment_u64s[]; -+ -+/* Configured maximum VLAN headers. */ -+extern int flow_vlan_limit; -+ -+#define FLOW_U64_OFFSET(FIELD) \ -+ (offsetof(struct flow, FIELD) / sizeof(uint64_t)) -+#define FLOW_U64_OFFREM(FIELD) \ -+ (offsetof(struct flow, FIELD) % sizeof(uint64_t)) -+ -+/* Number of 64-bit units spanned by a 'FIELD'. */ -+#define FLOW_U64_SIZE(FIELD) \ -+ DIV_ROUND_UP(FLOW_U64_OFFREM(FIELD) + MEMBER_SIZEOF(struct flow, FIELD), \ -+ sizeof(uint64_t)) -+ -+void flow_extract(struct dp_packet *, struct flow *); -+ -+void flow_zero_wildcards(struct flow *, const struct flow_wildcards *); -+void flow_unwildcard_tp_ports(const struct flow *, struct flow_wildcards *); -+void flow_get_metadata(const struct flow *, struct match *flow_metadata); -+struct netdev *flow_get_tunnel_netdev(struct flow_tnl *tunnel); -+ -+const char *ct_state_to_string(uint32_t state); -+uint32_t ct_state_from_string(const char *); -+bool parse_ct_state(const char *state_str, uint32_t default_state, -+ uint32_t *ct_state, struct ds *); -+bool validate_ct_state(uint32_t state, struct ds *); -+void flow_clear_conntrack(struct flow *); -+ -+char *flow_to_string(const struct flow *, const struct ofputil_port_map *); -+void format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t), -+ uint32_t flags, char del); -+void format_flags_masked(struct ds *ds, const char *name, -+ const char *(*bit_to_string)(uint32_t), -+ uint32_t flags, uint32_t mask, uint32_t max_mask); -+void format_packet_type_masked(struct ds *, ovs_be32 value, ovs_be32 mask); -+int parse_flags(const char *s, const char *(*bit_to_string)(uint32_t), -+ char end, const char *field_name, char **res_string, -+ uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask); -+ -+void flow_format(struct ds *, const struct flow *, -+ const struct ofputil_port_map *); -+void flow_print(FILE *, const struct flow *, const struct ofputil_port_map *); -+static inline int flow_compare_3way(const struct flow *, const struct flow *); -+static inline bool flow_equal(const struct flow *, const struct flow *); -+static inline size_t flow_hash(const struct flow *, uint32_t basis); -+ -+void flow_set_dl_vlan(struct flow *, ovs_be16 vid, int id); -+void flow_fix_vlan_tpid(struct flow *); -+void flow_set_vlan_vid(struct flow *, ovs_be16 vid); -+void flow_set_vlan_pcp(struct flow *, uint8_t pcp, int id); -+ -+void flow_limit_vlans(int vlan_limit); -+int flow_count_vlan_headers(const struct flow *); -+void flow_skip_common_vlan_headers(const struct flow *a, int *p_an, -+ const struct flow *b, int *p_bn); -+void flow_pop_vlan(struct flow*, struct flow_wildcards*); -+void flow_push_vlan_uninit(struct flow*, struct flow_wildcards*); -+ -+int flow_count_mpls_labels(const struct flow *, struct flow_wildcards *); -+int flow_count_common_mpls_labels(const struct flow *a, int an, -+ const struct flow *b, int bn, -+ struct flow_wildcards *wc); -+void flow_push_mpls(struct flow *, int n, ovs_be16 mpls_eth_type, -+ struct flow_wildcards *, bool clear_flow_L3); -+bool flow_pop_mpls(struct flow *, int n, ovs_be16 eth_type, -+ struct flow_wildcards *); -+void flow_set_mpls_label(struct flow *, int idx, ovs_be32 label); -+void flow_set_mpls_ttl(struct flow *, int idx, uint8_t ttl); -+void flow_set_mpls_tc(struct flow *, int idx, uint8_t tc); -+void flow_set_mpls_bos(struct flow *, int idx, uint8_t stack); -+void flow_set_mpls_lse(struct flow *, int idx, ovs_be32 lse); -+ -+void flow_compose(struct dp_packet *, const struct flow *, -+ const void *l7, size_t l7_len); -+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); -+bool parse_nsh(const void **datap, size_t *sizep, struct ovs_key_nsh *key); -+uint16_t parse_tcp_flags(struct dp_packet *packet, ovs_be16 *dl_type_p, -+ uint8_t *nw_frag_p, ovs_be16 *first_vlan_tci_p); -+ -+static inline uint64_t -+flow_get_xreg(const struct flow *flow, int idx) -+{ -+ return ((uint64_t) flow->regs[idx * 2] << 32) | flow->regs[idx * 2 + 1]; -+} -+ -+static inline void -+flow_set_xreg(struct flow *flow, int idx, uint64_t value) -+{ -+ flow->regs[idx * 2] = value >> 32; -+ flow->regs[idx * 2 + 1] = value; -+} -+ -+static inline ovs_u128 -+flow_get_xxreg(const struct flow *flow, int idx) -+{ -+ ovs_u128 value; -+ -+ value.u64.hi = (uint64_t) flow->regs[idx * 4] << 32; -+ value.u64.hi |= flow->regs[idx * 4 + 1]; -+ value.u64.lo = (uint64_t) flow->regs[idx * 4 + 2] << 32; -+ value.u64.lo |= flow->regs[idx * 4 + 3]; -+ -+ return value; -+} -+ -+static inline void -+flow_set_xxreg(struct flow *flow, int idx, ovs_u128 value) -+{ -+ flow->regs[idx * 4] = value.u64.hi >> 32; -+ flow->regs[idx * 4 + 1] = value.u64.hi; -+ flow->regs[idx * 4 + 2] = value.u64.lo >> 32; -+ flow->regs[idx * 4 + 3] = value.u64.lo; -+} -+ -+static inline int -+flow_compare_3way(const struct flow *a, const struct flow *b) -+{ -+ return memcmp(a, b, sizeof *a); -+} -+ -+static inline bool -+flow_equal(const struct flow *a, const struct flow *b) -+{ -+ return !flow_compare_3way(a, b); -+} -+ -+static inline size_t -+flow_hash(const struct flow *flow, uint32_t basis) -+{ -+ return hash_bytes64((const uint64_t *)flow, sizeof *flow, basis); -+} -+ -+static inline uint16_t -+ofp_to_u16(ofp_port_t ofp_port) -+{ -+ return (OVS_FORCE uint16_t) ofp_port; -+} -+ -+static inline uint32_t -+odp_to_u32(odp_port_t odp_port) -+{ -+ return (OVS_FORCE uint32_t) odp_port; -+} -+ -+static inline uint32_t -+ofp11_to_u32(ofp11_port_t ofp11_port) -+{ -+ return (OVS_FORCE uint32_t) ofp11_port; -+} -+ -+static inline ofp_port_t -+u16_to_ofp(uint16_t port) -+{ -+ return OFP_PORT_C(port); -+} -+ -+static inline odp_port_t -+u32_to_odp(uint32_t port) -+{ -+ return ODP_PORT_C(port); -+} -+ -+static inline ofp11_port_t -+u32_to_ofp11(uint32_t port) -+{ -+ return OFP11_PORT_C(port); -+} -+ -+static inline uint32_t -+hash_ofp_port(ofp_port_t ofp_port) -+{ -+ return hash_int(ofp_to_u16(ofp_port), 0); -+} -+ -+static inline uint32_t -+hash_odp_port(odp_port_t odp_port) -+{ -+ return hash_int(odp_to_u32(odp_port), 0); -+} -+ -+uint32_t flow_hash_5tuple(const struct flow *flow, uint32_t basis); -+uint32_t flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis); -+uint32_t flow_hash_symmetric_l2(const struct flow *flow, uint32_t basis); -+uint32_t flow_hash_symmetric_l3l4(const struct flow *flow, uint32_t basis, -+ bool inc_udp_ports ); -+uint32_t flow_hash_symmetric_l3(const struct flow *flow, uint32_t basis); -+ -+/* Initialize a flow with random fields that matter for nx_hash_fields. */ -+void flow_random_hash_fields(struct flow *); -+void flow_mask_hash_fields(const struct flow *, struct flow_wildcards *, -+ enum nx_hash_fields); -+uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields, -+ uint16_t basis); -+const char *flow_hash_fields_to_str(enum nx_hash_fields); -+bool flow_hash_fields_valid(enum nx_hash_fields); -+ -+uint32_t flow_hash_in_wildcards(const struct flow *, -+ const struct flow_wildcards *, -+ uint32_t basis); -+ -+bool flow_equal_except(const struct flow *a, const struct flow *b, -+ const struct flow_wildcards *); -+ -+/* Bitmap for flow values. For each 1-bit the corresponding flow value is -+ * explicitly specified, other values are zeroes. -+ * -+ * map_t must be wide enough to hold any member of struct flow. */ -+typedef unsigned long long map_t; -+#define MAP_T_BITS (sizeof(map_t) * CHAR_BIT) -+#define MAP_1 (map_t)1 -+#define MAP_MAX TYPE_MAXIMUM(map_t) -+ -+#define MAP_IS_SET(MAP, IDX) ((MAP) & (MAP_1 << (IDX))) -+ -+/* Iterate through the indices of all 1-bits in 'MAP'. */ -+#define MAP_FOR_EACH_INDEX(IDX, MAP) \ -+ ULLONG_FOR_EACH_1(IDX, MAP) -+ -+#define FLOWMAP_UNITS DIV_ROUND_UP(FLOW_U64S, MAP_T_BITS) -+ -+struct flowmap { -+ map_t bits[FLOWMAP_UNITS]; -+}; -+ -+#define FLOWMAP_EMPTY_INITIALIZER { { 0 } } -+ -+static inline void flowmap_init(struct flowmap *); -+static inline bool flowmap_equal(struct flowmap, struct flowmap); -+static inline bool flowmap_is_set(const struct flowmap *, size_t idx); -+static inline bool flowmap_are_set(const struct flowmap *, size_t idx, -+ unsigned int n_bits); -+static inline void flowmap_set(struct flowmap *, size_t idx, -+ unsigned int n_bits); -+static inline void flowmap_clear(struct flowmap *, size_t idx, -+ unsigned int n_bits); -+static inline struct flowmap flowmap_or(struct flowmap, struct flowmap); -+static inline struct flowmap flowmap_and(struct flowmap, struct flowmap); -+static inline bool flowmap_is_empty(struct flowmap); -+static inline unsigned int flowmap_n_1bits(struct flowmap); -+ -+#define FLOWMAP_HAS_FIELD(FM, FIELD) \ -+ flowmap_are_set(FM, FLOW_U64_OFFSET(FIELD), FLOW_U64_SIZE(FIELD)) -+ -+#define FLOWMAP_SET(FM, FIELD) \ -+ flowmap_set(FM, FLOW_U64_OFFSET(FIELD), FLOW_U64_SIZE(FIELD)) -+ -+#define FLOWMAP_SET__(FM, FIELD, SIZE) \ -+ flowmap_set(FM, FLOW_U64_OFFSET(FIELD), \ -+ DIV_ROUND_UP(SIZE, sizeof(uint64_t))) -+ -+/* XXX: Only works for full 64-bit units. */ -+#define FLOWMAP_CLEAR(FM, FIELD) \ -+ BUILD_ASSERT_DECL(FLOW_U64_OFFREM(FIELD) == 0); \ -+ BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->FIELD) % sizeof(uint64_t) == 0); \ -+ flowmap_clear(FM, FLOW_U64_OFFSET(FIELD), FLOW_U64_SIZE(FIELD)) -+ -+/* Iterate through all units in 'FMAP'. */ -+#define FLOWMAP_FOR_EACH_UNIT(UNIT) \ -+ for ((UNIT) = 0; (UNIT) < FLOWMAP_UNITS; (UNIT)++) -+ -+/* Iterate through all map units in 'FMAP'. */ -+#define FLOWMAP_FOR_EACH_MAP(MAP, FLOWMAP) \ -+ for (size_t unit__ = 0; \ -+ unit__ < FLOWMAP_UNITS && ((MAP) = (FLOWMAP).bits[unit__], true); \ -+ unit__++) -+ -+struct flowmap_aux; -+static inline bool flowmap_next_index(struct flowmap_aux *, size_t *idx); -+ -+#define FLOWMAP_AUX_INITIALIZER(FLOWMAP) { .unit = 0, .map = (FLOWMAP) } -+ -+/* Iterate through all struct flow u64 indices specified by 'MAP'. This is a -+ * slower but easier version of the FLOWMAP_FOR_EACH_MAP() & -+ * MAP_FOR_EACH_INDEX() combination. */ -+#define FLOWMAP_FOR_EACH_INDEX(IDX, MAP) \ -+ for (struct flowmap_aux aux__ = FLOWMAP_AUX_INITIALIZER(MAP); \ -+ flowmap_next_index(&aux__, &(IDX));) -+ -+/* Flowmap inline implementations. */ -+static inline void -+flowmap_init(struct flowmap *fm) -+{ -+ memset(fm, 0, sizeof *fm); -+} -+ -+static inline bool -+flowmap_equal(struct flowmap a, struct flowmap b) -+{ -+ return !memcmp(&a, &b, sizeof a); -+} -+ -+static inline bool -+flowmap_is_set(const struct flowmap *fm, size_t idx) -+{ -+ return (fm->bits[idx / MAP_T_BITS] & (MAP_1 << (idx % MAP_T_BITS))) != 0; -+} -+ -+/* Returns 'true' if any of the 'n_bits' bits starting at 'idx' are set in -+ * 'fm'. 'n_bits' can be at most MAP_T_BITS. */ -+static inline bool -+flowmap_are_set(const struct flowmap *fm, size_t idx, unsigned int n_bits) -+{ -+ map_t n_bits_mask = (MAP_1 << n_bits) - 1; -+ size_t unit = idx / MAP_T_BITS; -+ -+ idx %= MAP_T_BITS; -+ -+ if (fm->bits[unit] & (n_bits_mask << idx)) { -+ return true; -+ } -+ /* The seemingly unnecessary bounds check on 'unit' is a workaround for a -+ * false-positive array out of bounds error by GCC 4.9. */ -+ if (unit + 1 < FLOWMAP_UNITS && idx + n_bits > MAP_T_BITS) { -+ /* Check the remaining bits from the next unit. */ -+ return fm->bits[unit + 1] & (n_bits_mask >> (MAP_T_BITS - idx)); -+ } -+ return false; -+} -+ -+/* Set the 'n_bits' consecutive bits in 'fm', starting at bit 'idx'. -+ * 'n_bits' can be at most MAP_T_BITS. */ -+static inline void -+flowmap_set(struct flowmap *fm, size_t idx, unsigned int n_bits) -+{ -+ map_t n_bits_mask = (MAP_1 << n_bits) - 1; -+ size_t unit = idx / MAP_T_BITS; -+ -+ idx %= MAP_T_BITS; -+ -+ fm->bits[unit] |= n_bits_mask << idx; -+ /* The seemingly unnecessary bounds check on 'unit' is a workaround for a -+ * false-positive array out of bounds error by GCC 4.9. */ -+ if (unit + 1 < FLOWMAP_UNITS && idx + n_bits > MAP_T_BITS) { -+ /* 'MAP_T_BITS - idx' bits were set on 'unit', set the remaining -+ * bits from the next unit. */ -+ fm->bits[unit + 1] |= n_bits_mask >> (MAP_T_BITS - idx); -+ } -+} -+ -+/* Clears the 'n_bits' consecutive bits in 'fm', starting at bit 'idx'. -+ * 'n_bits' can be at most MAP_T_BITS. */ -+static inline void -+flowmap_clear(struct flowmap *fm, size_t idx, unsigned int n_bits) -+{ -+ map_t n_bits_mask = (MAP_1 << n_bits) - 1; -+ size_t unit = idx / MAP_T_BITS; -+ -+ idx %= MAP_T_BITS; -+ -+ fm->bits[unit] &= ~(n_bits_mask << idx); -+ /* The seemingly unnecessary bounds check on 'unit' is a workaround for a -+ * false-positive array out of bounds error by GCC 4.9. */ -+ if (unit + 1 < FLOWMAP_UNITS && idx + n_bits > MAP_T_BITS) { -+ /* 'MAP_T_BITS - idx' bits were cleared on 'unit', clear the -+ * remaining bits from the next unit. */ -+ fm->bits[unit + 1] &= ~(n_bits_mask >> (MAP_T_BITS - idx)); -+ } -+} -+ -+/* OR the bits in the flowmaps. */ -+static inline struct flowmap -+flowmap_or(struct flowmap a, struct flowmap b) -+{ -+ struct flowmap map; -+ size_t unit; -+ -+ FLOWMAP_FOR_EACH_UNIT (unit) { -+ map.bits[unit] = a.bits[unit] | b.bits[unit]; -+ } -+ return map; -+} -+ -+/* AND the bits in the flowmaps. */ -+static inline struct flowmap -+flowmap_and(struct flowmap a, struct flowmap b) -+{ -+ struct flowmap map; -+ size_t unit; -+ -+ FLOWMAP_FOR_EACH_UNIT (unit) { -+ map.bits[unit] = a.bits[unit] & b.bits[unit]; -+ } -+ return map; -+} -+ -+static inline bool -+flowmap_is_empty(struct flowmap fm) -+{ -+ map_t map; -+ -+ FLOWMAP_FOR_EACH_MAP (map, fm) { -+ if (map) { -+ return false; -+ } -+ } -+ return true; -+} -+ -+static inline unsigned int -+flowmap_n_1bits(struct flowmap fm) -+{ -+ unsigned int n_1bits = 0; -+ size_t unit; -+ -+ FLOWMAP_FOR_EACH_UNIT (unit) { -+ n_1bits += count_1bits(fm.bits[unit]); -+ } -+ return n_1bits; -+} -+ -+struct flowmap_aux { -+ size_t unit; -+ struct flowmap map; -+}; -+ -+static inline bool -+flowmap_next_index(struct flowmap_aux *aux, size_t *idx) -+{ -+ for (;;) { -+ map_t *map = &aux->map.bits[aux->unit]; -+ if (*map) { -+ *idx = aux->unit * MAP_T_BITS + raw_ctz(*map); -+ *map = zero_rightmost_1bit(*map); -+ return true; -+ } -+ if (++aux->unit >= FLOWMAP_UNITS) { -+ return false; -+ } -+ } -+} -+ -+ -+/* Compressed flow. */ -+ -+/* A sparse representation of a "struct flow". -+ * -+ * A "struct flow" is fairly large and tends to be mostly zeros. Sparse -+ * representation has two advantages. First, it saves memory and, more -+ * importantly, minimizes the number of accessed cache lines. Second, it saves -+ * time when the goal is to iterate over only the nonzero parts of the struct. -+ * -+ * The map member hold one bit for each uint64_t in a "struct flow". Each -+ * 0-bit indicates that the corresponding uint64_t is zero, each 1-bit that it -+ * *may* be nonzero (see below how this applies to minimasks). -+ * -+ * The values indicated by 'map' always follow the miniflow in memory. The -+ * user of the miniflow is responsible for always having enough storage after -+ * the struct miniflow corresponding to the number of 1-bits in maps. -+ * -+ * Elements in values array are allowed to be zero. This is useful for "struct -+ * minimatch", for which ensuring that the miniflow and minimask members have -+ * same maps allows optimization. This allowance applies only to a miniflow -+ * that is not a mask. That is, a minimask may NOT have zero elements in its -+ * values. -+ * -+ * A miniflow is always dynamically allocated so that the maps are followed by -+ * at least as many elements as there are 1-bits in maps. */ -+struct miniflow { -+ struct flowmap map; -+ /* Followed by: -+ * uint64_t values[n]; -+ * where 'n' is miniflow_n_values(miniflow). */ -+}; -+BUILD_ASSERT_DECL(sizeof(struct miniflow) % sizeof(uint64_t) == 0); -+ -+#define MINIFLOW_VALUES_SIZE(COUNT) ((COUNT) * sizeof(uint64_t)) -+ -+static inline uint64_t *miniflow_values(struct miniflow *mf) -+{ -+ return (uint64_t *)(mf + 1); -+} -+ -+static inline const uint64_t *miniflow_get_values(const struct miniflow *mf) -+{ -+ return (const uint64_t *)(mf + 1); -+} -+ -+struct pkt_metadata; -+ -+/* The 'dst' must follow with buffer space for FLOW_U64S 64-bit units. -+ * 'dst->map' is ignored on input and set on output to indicate which fields -+ * were extracted. */ -+void miniflow_extract(struct dp_packet *packet, struct miniflow *dst); -+void miniflow_map_init(struct miniflow *, const struct flow *); -+void flow_wc_map(const struct flow *, struct flowmap *); -+size_t miniflow_alloc(struct miniflow *dsts[], size_t n, -+ const struct miniflow *src); -+void miniflow_init(struct miniflow *, const struct flow *); -+void miniflow_clone(struct miniflow *, const struct miniflow *, -+ size_t n_values); -+struct miniflow * miniflow_create(const struct flow *); -+ -+void miniflow_expand(const struct miniflow *, struct flow *); -+ -+static inline uint64_t flow_u64_value(const struct flow *flow, size_t index) -+{ -+ return ((uint64_t *)flow)[index]; -+} -+ -+static inline uint64_t *flow_u64_lvalue(struct flow *flow, size_t index) -+{ -+ return &((uint64_t *)flow)[index]; -+} -+ -+static inline size_t -+miniflow_n_values(const struct miniflow *flow) -+{ -+ return flowmap_n_1bits(flow->map); -+} -+ -+struct flow_for_each_in_maps_aux { -+ const struct flow *flow; -+ struct flowmap_aux map_aux; -+}; -+ -+static inline bool -+flow_values_get_next_in_maps(struct flow_for_each_in_maps_aux *aux, -+ uint64_t *value) -+{ -+ size_t idx; -+ -+ if (flowmap_next_index(&aux->map_aux, &idx)) { -+ *value = flow_u64_value(aux->flow, idx); -+ return true; -+ } -+ return false; -+} -+ -+/* Iterate through all flow u64 values specified by 'MAPS'. */ -+#define FLOW_FOR_EACH_IN_MAPS(VALUE, FLOW, MAPS) \ -+ for (struct flow_for_each_in_maps_aux aux__ \ -+ = { (FLOW), FLOWMAP_AUX_INITIALIZER(MAPS) }; \ -+ flow_values_get_next_in_maps(&aux__, &(VALUE));) -+ -+struct mf_for_each_in_map_aux { -+ size_t unit; /* Current 64-bit unit of the flowmaps -+ being processed. */ -+ struct flowmap fmap; /* Remaining 1-bits corresponding to the -+ 64-bit words in 'values' */ -+ struct flowmap map; /* Remaining 1-bits corresponding to the -+ 64-bit words of interest. */ -+ const uint64_t *values; /* 64-bit words corresponding to the -+ 1-bits in 'fmap'. */ -+}; -+ -+/* Get the data from 'aux->values' corresponding to the next lowest 1-bit -+ * in 'aux->map', given that 'aux->values' points to an array of 64-bit -+ * words corresponding to the 1-bits in 'aux->fmap', starting from the -+ * rightmost 1-bit. -+ * -+ * Returns 'true' if the traversal is incomplete, 'false' otherwise. -+ * 'aux' is prepared for the next iteration after each call. -+ * -+ * This is used to traverse through, for example, the values in a miniflow -+ * representation of a flow key selected by non-zero 64-bit words in a -+ * corresponding subtable mask. */ -+static inline bool -+mf_get_next_in_map(struct mf_for_each_in_map_aux *aux, -+ uint64_t *value) -+{ -+ map_t *map, *fmap; -+ map_t rm1bit; -+ -+ /* Skip empty map units. */ -+ while (OVS_UNLIKELY(!*(map = &aux->map.bits[aux->unit]))) { -+ /* Skip remaining data in the current unit before advancing -+ * to the next. */ -+ aux->values += count_1bits(aux->fmap.bits[aux->unit]); -+ if (++aux->unit == FLOWMAP_UNITS) { -+ return false; -+ } -+ } -+ -+ rm1bit = rightmost_1bit(*map); -+ *map -= rm1bit; -+ fmap = &aux->fmap.bits[aux->unit]; -+ -+ /* If the rightmost 1-bit found from the current unit in 'aux->map' -+ * ('rm1bit') is also present in 'aux->fmap', store the corresponding -+ * value from 'aux->values' to '*value', otherwise store 0. */ -+ if (OVS_LIKELY(*fmap & rm1bit)) { -+ /* Skip all 64-bit words in 'values' preceding the one corresponding -+ * to 'rm1bit'. */ -+ map_t trash = *fmap & (rm1bit - 1); -+ -+ /* Avoid resetting 'fmap' and calling count_1bits() when trash is -+ * zero. */ -+ if (trash) { -+ *fmap -= trash; -+ aux->values += count_1bits(trash); -+ } -+ -+ *value = *aux->values; -+ } else { -+ *value = 0; -+ } -+ return true; -+} -+ -+/* Iterate through miniflow u64 values specified by 'FLOWMAP'. */ -+#define MINIFLOW_FOR_EACH_IN_FLOWMAP(VALUE, FLOW, FLOWMAP) \ -+ for (struct mf_for_each_in_map_aux aux__ = \ -+ { 0, (FLOW)->map, (FLOWMAP), miniflow_get_values(FLOW) }; \ -+ mf_get_next_in_map(&aux__, &(VALUE));) -+ -+/* This can be used when it is known that 'idx' is set in 'map'. */ -+static inline const uint64_t * -+miniflow_values_get__(const uint64_t *values, map_t map, size_t idx) -+{ -+ return values + count_1bits(map & ((MAP_1 << idx) - 1)); -+} -+ -+/* This can be used when it is known that 'u64_idx' is set in -+ * the map of 'mf'. */ -+static inline const uint64_t * -+miniflow_get__(const struct miniflow *mf, size_t idx) -+{ -+ const uint64_t *values = miniflow_get_values(mf); -+ const map_t *map = mf->map.bits; -+ -+ while (idx >= MAP_T_BITS) { -+ idx -= MAP_T_BITS; -+ values += count_1bits(*map++); -+ } -+ return miniflow_values_get__(values, *map, idx); -+} -+ -+#define MINIFLOW_IN_MAP(MF, IDX) flowmap_is_set(&(MF)->map, IDX) -+ -+/* Get the value of the struct flow 'FIELD' as up to 8 byte wide integer type -+ * 'TYPE' from miniflow 'MF'. */ -+#define MINIFLOW_GET_TYPE(MF, TYPE, FIELD) \ -+ (BUILD_ASSERT(sizeof(TYPE) == sizeof(((struct flow *)0)->FIELD)), \ -+ BUILD_ASSERT_GCCONLY(__builtin_types_compatible_p(TYPE, typeof(((struct flow *)0)->FIELD))), \ -+ MINIFLOW_GET_TYPE__(MF, TYPE, FIELD)) -+ -+/* Like MINIFLOW_GET_TYPE, but without checking that TYPE is the correct width -+ * for FIELD. (This is useful for deliberately reading adjacent fields in one -+ * go.) */ -+#define MINIFLOW_GET_TYPE__(MF, TYPE, FIELD) \ -+ (MINIFLOW_IN_MAP(MF, FLOW_U64_OFFSET(FIELD)) \ -+ ? ((OVS_FORCE const TYPE *)miniflow_get__(MF, FLOW_U64_OFFSET(FIELD))) \ -+ [FLOW_U64_OFFREM(FIELD) / sizeof(TYPE)] \ -+ : 0) -+ -+#define MINIFLOW_GET_U128(FLOW, FIELD) \ -+ (ovs_u128) { .u64 = { \ -+ (MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD)) ? \ -+ *miniflow_get__(FLOW, FLOW_U64_OFFSET(FIELD)) : 0), \ -+ (MINIFLOW_IN_MAP(FLOW, FLOW_U64_OFFSET(FIELD) + 1) ? \ -+ *miniflow_get__(FLOW, FLOW_U64_OFFSET(FIELD) + 1) : 0) } } -+ -+#define MINIFLOW_GET_U8(FLOW, FIELD) \ -+ MINIFLOW_GET_TYPE(FLOW, uint8_t, FIELD) -+#define MINIFLOW_GET_U16(FLOW, FIELD) \ -+ MINIFLOW_GET_TYPE(FLOW, uint16_t, FIELD) -+#define MINIFLOW_GET_BE16(FLOW, FIELD) \ -+ MINIFLOW_GET_TYPE(FLOW, ovs_be16, FIELD) -+#define MINIFLOW_GET_U32(FLOW, FIELD) \ -+ MINIFLOW_GET_TYPE(FLOW, uint32_t, FIELD) -+#define MINIFLOW_GET_BE32(FLOW, FIELD) \ -+ MINIFLOW_GET_TYPE(FLOW, ovs_be32, FIELD) -+#define MINIFLOW_GET_U64(FLOW, FIELD) \ -+ MINIFLOW_GET_TYPE(FLOW, uint64_t, FIELD) -+#define MINIFLOW_GET_BE64(FLOW, FIELD) \ -+ MINIFLOW_GET_TYPE(FLOW, ovs_be64, FIELD) -+ -+static inline uint64_t miniflow_get(const struct miniflow *, -+ unsigned int u64_ofs); -+static inline uint32_t miniflow_get_u32(const struct miniflow *, -+ unsigned int u32_ofs); -+static inline ovs_be32 miniflow_get_be32(const struct miniflow *, -+ unsigned int be32_ofs); -+static inline uint16_t miniflow_get_vid(const struct miniflow *, size_t); -+static inline uint16_t miniflow_get_tcp_flags(const struct miniflow *); -+static inline ovs_be64 miniflow_get_metadata(const struct miniflow *); -+static inline uint64_t miniflow_get_tun_metadata_present_map( -+ const struct miniflow *); -+static inline uint32_t miniflow_get_recirc_id(const struct miniflow *); -+static inline uint32_t miniflow_get_dp_hash(const struct miniflow *); -+static inline ovs_be32 miniflow_get_ports(const struct miniflow *); -+ -+bool miniflow_equal(const struct miniflow *a, const struct miniflow *b); -+bool miniflow_equal_in_minimask(const struct miniflow *a, -+ const struct miniflow *b, -+ const struct minimask *); -+bool miniflow_equal_flow_in_minimask(const struct miniflow *a, -+ const struct flow *b, -+ const struct minimask *); -+uint32_t miniflow_hash_5tuple(const struct miniflow *flow, uint32_t basis); -+ -+ -+/* Compressed flow wildcards. */ -+ -+/* A sparse representation of a "struct flow_wildcards". -+ * -+ * See the large comment on struct miniflow for details. -+ * -+ * Note: While miniflow can have zero data for a 1-bit in the map, -+ * a minimask may not! We rely on this in the implementation. */ -+struct minimask { -+ struct miniflow masks; -+}; -+ -+void minimask_init(struct minimask *, const struct flow_wildcards *); -+struct minimask * minimask_create(const struct flow_wildcards *); -+void minimask_combine(struct minimask *dst, -+ const struct minimask *a, const struct minimask *b, -+ uint64_t storage[FLOW_U64S]); -+ -+void minimask_expand(const struct minimask *, struct flow_wildcards *); -+ -+static inline uint32_t minimask_get_u32(const struct minimask *, -+ unsigned int u32_ofs); -+static inline ovs_be32 minimask_get_be32(const struct minimask *, -+ unsigned int be32_ofs); -+static inline uint16_t minimask_get_vid_mask(const struct minimask *, size_t); -+static inline ovs_be64 minimask_get_metadata_mask(const struct minimask *); -+ -+bool minimask_equal(const struct minimask *a, const struct minimask *b); -+bool minimask_has_extra(const struct minimask *, const struct minimask *); -+ -+ -+/* Returns true if 'mask' matches every packet, false if 'mask' fixes any bits -+ * or fields. */ -+static inline bool -+minimask_is_catchall(const struct minimask *mask) -+{ -+ /* For every 1-bit in mask's map, the corresponding value is non-zero, -+ * so the only way the mask can not fix any bits or fields is for the -+ * map the be zero. */ -+ return flowmap_is_empty(mask->masks.map); -+} -+ -+/* Returns the uint64_t that would be at byte offset '8 * u64_ofs' if 'flow' -+ * were expanded into a "struct flow". */ -+static inline uint64_t miniflow_get(const struct miniflow *flow, -+ unsigned int u64_ofs) -+{ -+ return MINIFLOW_IN_MAP(flow, u64_ofs) ? *miniflow_get__(flow, u64_ofs) : 0; -+} -+ -+static inline uint32_t miniflow_get_u32(const struct miniflow *flow, -+ unsigned int u32_ofs) -+{ -+ uint64_t value = miniflow_get(flow, u32_ofs / 2); -+ -+#if WORDS_BIGENDIAN -+ return (u32_ofs & 1) ? value : value >> 32; -+#else -+ return (u32_ofs & 1) ? value >> 32 : value; -+#endif -+} -+ -+static inline ovs_be32 miniflow_get_be32(const struct miniflow *flow, -+ unsigned int be32_ofs) -+{ -+ return (OVS_FORCE ovs_be32)miniflow_get_u32(flow, be32_ofs); -+} -+ -+/* Returns the VID within the vlan_tci member of the "struct flow" represented -+ * by 'flow'. */ -+static inline uint16_t -+miniflow_get_vid(const struct miniflow *flow, size_t n) -+{ -+ if (n < FLOW_MAX_VLAN_HEADERS) { -+ union flow_vlan_hdr hdr = { -+ .qtag = MINIFLOW_GET_BE32(flow, vlans[n].qtag) -+ }; -+ return vlan_tci_to_vid(hdr.tci); -+ } -+ return 0; -+} -+ -+/* Returns the uint32_t that would be at byte offset '4 * u32_ofs' if 'mask' -+ * were expanded into a "struct flow_wildcards". */ -+static inline uint32_t -+minimask_get_u32(const struct minimask *mask, unsigned int u32_ofs) -+{ -+ return miniflow_get_u32(&mask->masks, u32_ofs); -+} -+ -+static inline ovs_be32 -+minimask_get_be32(const struct minimask *mask, unsigned int be32_ofs) -+{ -+ return (OVS_FORCE ovs_be32)minimask_get_u32(mask, be32_ofs); -+} -+ -+/* Returns the VID mask within the vlan_tci member of the "struct -+ * flow_wildcards" represented by 'mask'. */ -+static inline uint16_t -+minimask_get_vid_mask(const struct minimask *mask, size_t n) -+{ -+ return miniflow_get_vid(&mask->masks, n); -+} -+ -+/* Returns the value of the "tcp_flags" field in 'flow'. */ -+static inline uint16_t -+miniflow_get_tcp_flags(const struct miniflow *flow) -+{ -+ return ntohs(MINIFLOW_GET_BE16(flow, tcp_flags)); -+} -+ -+/* Returns the value of the OpenFlow 1.1+ "metadata" field in 'flow'. */ -+static inline ovs_be64 -+miniflow_get_metadata(const struct miniflow *flow) -+{ -+ return MINIFLOW_GET_BE64(flow, metadata); -+} -+ -+/* Returns the bitmap that indicates which tunnel metadata fields are present -+ * in 'flow'. */ -+static inline uint64_t -+miniflow_get_tun_metadata_present_map(const struct miniflow *flow) -+{ -+ return MINIFLOW_GET_U64(flow, tunnel.metadata.present.map); -+} -+ -+/* Returns the recirc_id in 'flow.' */ -+static inline uint32_t -+miniflow_get_recirc_id(const struct miniflow *flow) -+{ -+ return MINIFLOW_GET_U32(flow, recirc_id); -+} -+ -+/* Returns the dp_hash in 'flow.' */ -+static inline uint32_t -+miniflow_get_dp_hash(const struct miniflow *flow) -+{ -+ return MINIFLOW_GET_U32(flow, dp_hash); -+} -+ -+/* Returns the 'tp_src' and 'tp_dst' fields together as one piece of data. */ -+static inline ovs_be32 -+miniflow_get_ports(const struct miniflow *flow) -+{ -+ return MINIFLOW_GET_TYPE__(flow, ovs_be32, tp_src); -+} -+ -+/* Returns the mask for the OpenFlow 1.1+ "metadata" field in 'mask'. -+ * -+ * The return value is all-1-bits if 'mask' matches on the whole value of the -+ * metadata field, all-0-bits if 'mask' entirely wildcards the metadata field, -+ * or some other value if the metadata field is partially matched, partially -+ * wildcarded. */ -+static inline ovs_be64 -+minimask_get_metadata_mask(const struct minimask *mask) -+{ -+ return MINIFLOW_GET_BE64(&mask->masks, metadata); -+} -+ -+/* Perform a bitwise OR of miniflow 'src' flow data specified in 'subset' with -+ * the equivalent fields in 'dst', storing the result in 'dst'. 'subset' must -+ * be a subset of 'src's map. */ -+static inline void -+flow_union_with_miniflow_subset(struct flow *dst, const struct miniflow *src, -+ struct flowmap subset) -+{ -+ uint64_t *dst_u64 = (uint64_t *) dst; -+ const uint64_t *p = miniflow_get_values(src); -+ map_t map; -+ -+ FLOWMAP_FOR_EACH_MAP (map, subset) { -+ size_t idx; -+ -+ MAP_FOR_EACH_INDEX(idx, map) { -+ dst_u64[idx] |= *p++; -+ } -+ dst_u64 += MAP_T_BITS; -+ } -+} -+ -+/* Perform a bitwise OR of miniflow 'src' flow data with the equivalent -+ * fields in 'dst', storing the result in 'dst'. */ -+static inline void -+flow_union_with_miniflow(struct flow *dst, const struct miniflow *src) -+{ -+ flow_union_with_miniflow_subset(dst, src, src->map); -+} -+ -+static inline bool is_ct_valid(const struct flow *flow, -+ const struct flow_wildcards *mask, -+ struct flow_wildcards *wc) -+{ -+ /* Matches are checked with 'mask' and without 'wc'. */ -+ if (mask && !wc) { -+ /* Must match at least one of the bits that implies a valid -+ * conntrack entry, or an explicit not-invalid. */ -+ return flow->ct_state & (CS_NEW | CS_ESTABLISHED | CS_RELATED -+ | CS_REPLY_DIR | CS_SRC_NAT | CS_DST_NAT) -+ || (flow->ct_state & CS_TRACKED -+ && mask->masks.ct_state & CS_INVALID -+ && !(flow->ct_state & CS_INVALID)); -+ } -+ /* Else we are checking a fully extracted flow, where valid CT state always -+ * has either 'new', 'established', or 'reply_dir' bit set. */ -+#define CS_VALID_MASK (CS_NEW | CS_ESTABLISHED | CS_REPLY_DIR) -+ if (wc) { -+ wc->masks.ct_state |= CS_VALID_MASK; -+ } -+ return flow->ct_state & CS_VALID_MASK; -+} -+ -+static inline void -+pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow) -+{ -+ /* Update this function whenever struct flow changes. */ -+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42); -+ -+ md->recirc_id = flow->recirc_id; -+ md->dp_hash = flow->dp_hash; -+ flow_tnl_copy__(&md->tunnel, &flow->tunnel); -+ md->skb_priority = flow->skb_priority; -+ md->pkt_mark = flow->pkt_mark; -+ md->in_port = flow->in_port; -+ md->ct_state = flow->ct_state; -+ md->ct_zone = flow->ct_zone; -+ md->ct_mark = flow->ct_mark; -+ md->ct_label = flow->ct_label; -+ -+ md->ct_orig_tuple_ipv6 = false; -+ if (flow->dl_type && is_ct_valid(flow, NULL, NULL)) { -+ if (flow->dl_type == htons(ETH_TYPE_IP)) { -+ md->ct_orig_tuple.ipv4 = (struct ovs_key_ct_tuple_ipv4) { -+ flow->ct_nw_src, -+ flow->ct_nw_dst, -+ flow->ct_tp_src, -+ flow->ct_tp_dst, -+ flow->ct_nw_proto, -+ }; -+ } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) { -+ md->ct_orig_tuple_ipv6 = true; -+ md->ct_orig_tuple.ipv6 = (struct ovs_key_ct_tuple_ipv6) { -+ flow->ct_ipv6_src, -+ flow->ct_ipv6_dst, -+ flow->ct_tp_src, -+ flow->ct_tp_dst, -+ flow->ct_nw_proto, -+ }; -+ } else { -+ /* Reset ct_orig_tuple for other types. */ -+ memset(&md->ct_orig_tuple, 0, sizeof md->ct_orig_tuple); -+ } -+ } else { -+ memset(&md->ct_orig_tuple, 0, sizeof md->ct_orig_tuple); -+ } -+} -+ -+/* Often, during translation we need to read a value from a flow('FLOW') and -+ * unwildcard the corresponding bits in the wildcards('WC'). This macro makes -+ * it easier to do that. */ -+ -+#define FLOW_WC_GET_AND_MASK_WC(FLOW, WC, FIELD) \ -+ (((WC) ? WC_MASK_FIELD(WC, FIELD) : NULL), ((FLOW)->FIELD)) -+ -+static inline bool is_ethernet(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (wc) { -+ WC_MASK_FIELD(wc, packet_type); -+ } -+ return flow->packet_type == htonl(PT_ETH); -+} -+ -+static inline ovs_be16 get_dl_type(const struct flow *flow) -+{ -+ if (flow->packet_type == htonl(PT_ETH)) { -+ return flow->dl_type; -+ } else if (pt_ns(flow->packet_type) == OFPHTN_ETHERTYPE) { -+ return pt_ns_type_be(flow->packet_type); -+ } else { -+ return htons(FLOW_DL_TYPE_NONE); -+ } -+} -+ -+static inline bool is_vlan(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (!is_ethernet(flow, wc)) { -+ return false; -+ } -+ if (wc) { -+ WC_MASK_FIELD_MASK(wc, vlans[0].tci, htons(VLAN_CFI)); -+ } -+ return (flow->vlans[0].tci & htons(VLAN_CFI)) != 0; -+} -+ -+static inline bool is_ip_any(const struct flow *flow) -+{ -+ return dl_type_is_ip_any(get_dl_type(flow)); -+} -+ -+static inline bool is_ip_proto(const struct flow *flow, uint8_t ip_proto, -+ struct flow_wildcards *wc) -+{ -+ if (is_ip_any(flow)) { -+ if (wc) { -+ WC_MASK_FIELD(wc, nw_proto); -+ } -+ return flow->nw_proto == ip_proto; -+ } -+ return false; -+} -+ -+static inline bool is_tcp(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ return is_ip_proto(flow, IPPROTO_TCP, wc); -+} -+ -+static inline bool is_udp(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ return is_ip_proto(flow, IPPROTO_UDP, wc); -+} -+ -+static inline bool is_sctp(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ return is_ip_proto(flow, IPPROTO_SCTP, wc); -+} -+ -+static inline bool is_icmpv4(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (get_dl_type(flow) == htons(ETH_TYPE_IP)) { -+ if (wc) { -+ memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); -+ } -+ return flow->nw_proto == IPPROTO_ICMP; -+ } -+ return false; -+} -+ -+static inline bool is_icmpv6(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (get_dl_type(flow) == htons(ETH_TYPE_IPV6)) { -+ if (wc) { -+ memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); -+ } -+ return flow->nw_proto == IPPROTO_ICMPV6; -+ } -+ return false; -+} -+ -+static inline bool is_nd(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (is_icmpv6(flow, wc)) { -+ if (wc) { -+ memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst); -+ } -+ if (flow->tp_dst != htons(0)) { -+ return false; -+ } -+ -+ if (wc) { -+ memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); -+ } -+ return (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || -+ flow->tp_src == htons(ND_NEIGHBOR_ADVERT)); -+ } -+ return false; -+} -+ -+static inline bool is_arp(const struct flow *flow) -+{ -+ return (flow->dl_type == htons(ETH_TYPE_ARP)); -+} -+ -+static inline bool is_garp(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (is_arp(flow)) { -+ return (FLOW_WC_GET_AND_MASK_WC(flow, wc, nw_src) == -+ FLOW_WC_GET_AND_MASK_WC(flow, wc, nw_dst)); -+ } -+ -+ return false; -+} -+ -+static inline bool is_igmp(const struct flow *flow, struct flow_wildcards *wc) -+{ -+ if (get_dl_type(flow) == htons(ETH_TYPE_IP)) { -+ if (wc) { -+ memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); -+ } -+ return flow->nw_proto == IPPROTO_IGMP; -+ } -+ return false; -+} -+ -+static inline bool is_mld(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (is_icmpv6(flow, wc)) { -+ if (wc) { -+ memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); -+ } -+ return (flow->tp_src == htons(MLD_QUERY) -+ || flow->tp_src == htons(MLD_REPORT) -+ || flow->tp_src == htons(MLD_DONE) -+ || flow->tp_src == htons(MLD2_REPORT)); -+ } -+ return false; -+} -+ -+static inline bool is_mld_query(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ if (is_icmpv6(flow, wc)) { -+ if (wc) { -+ memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); -+ } -+ return flow->tp_src == htons(MLD_QUERY); -+ } -+ return false; -+} -+ -+static inline bool is_mld_report(const struct flow *flow, -+ struct flow_wildcards *wc) -+{ -+ return is_mld(flow, wc) && !is_mld_query(flow, wc); -+} -+ -+static inline bool is_stp(const struct flow *flow) -+{ -+ return (flow->dl_type == htons(FLOW_DL_TYPE_NONE) -+ && eth_addr_equals(flow->dl_dst, eth_addr_stp)); -+} -+ -+/* Returns true if flow->tp_dst equals 'port'. If 'wc' is nonnull, sets -+ * appropriate bits in wc->masks.tp_dst to account for the test. -+ * -+ * The caller must already have ensured that 'flow' is a protocol for which -+ * tp_dst is relevant. */ -+static inline bool tp_dst_equals(const struct flow *flow, uint16_t port, -+ struct flow_wildcards *wc) -+{ -+ uint16_t diff = port ^ ntohs(flow->tp_dst); -+ if (wc) { -+ if (diff) { -+ /* Set mask for the most significant mismatching bit. */ -+ int ofs = raw_clz64((uint64_t) diff << 48); /* range [0,15] */ -+ wc->masks.tp_dst |= htons(0x8000 >> ofs); -+ } else { -+ /* Must match all bits. */ -+ wc->masks.tp_dst = OVS_BE16_MAX; -+ } -+ } -+ return !diff; -+} -+ -+#endif /* flow.h */ -Index: openvswitch-2.17.2/lib/hash.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/hash.h -+++ /dev/null -@@ -1,398 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2012, 2013, 2014, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --#ifndef HASH_H --#define HASH_H 1 -- --#include --#include --#include --#include --#include "util.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --static inline uint32_t --hash_rot(uint32_t x, int k) --{ -- return (x << k) | (x >> (32 - k)); --} -- --uint32_t hash_bytes(const void *, size_t n_bytes, uint32_t basis); --/* The hash input must be a word larger than 128 bits. */ --void hash_bytes128(const void *_, size_t n_bytes, uint32_t basis, -- ovs_u128 *out); -- --static inline uint32_t hash_int(uint32_t x, uint32_t basis); --static inline uint32_t hash_2words(uint32_t, uint32_t); --static inline uint32_t hash_uint64(const uint64_t); --static inline uint32_t hash_uint64_basis(const uint64_t x, -- const uint32_t basis); --uint32_t hash_3words(uint32_t, uint32_t, uint32_t); -- --static inline uint32_t hash_boolean(bool x, uint32_t basis); --uint32_t hash_double(double, uint32_t basis); -- --static inline uint32_t hash_pointer(const void *, uint32_t basis); --static inline uint32_t hash_string(const char *, uint32_t basis); -- --/* Murmurhash by Austin Appleby, -- * from https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp -- * -- * The upstream license there says: -- * -- * MurmurHash3 was written by Austin Appleby, and is placed in the public -- * domain. The author hereby disclaims copyright to this source code. -- * -- * See hash_words() for sample usage. */ -- --static inline uint32_t mhash_add__(uint32_t hash, uint32_t data) --{ -- /* zero-valued 'data' will not change the 'hash' value */ -- if (!data) { -- return hash; -- } -- -- data *= 0xcc9e2d51; -- data = hash_rot(data, 15); -- data *= 0x1b873593; -- return hash ^ data; --} -- --static inline uint32_t mhash_add(uint32_t hash, uint32_t data) --{ -- hash = mhash_add__(hash, data); -- hash = hash_rot(hash, 13); -- return hash * 5 + 0xe6546b64; --} -- --static inline uint32_t mhash_finish(uint32_t hash) --{ -- hash ^= hash >> 16; -- hash *= 0x85ebca6b; -- hash ^= hash >> 13; -- hash *= 0xc2b2ae35; -- hash ^= hash >> 16; -- return hash; --} -- --static inline uint32_t hash_add(uint32_t hash, uint32_t data); --static inline uint32_t hash_add64(uint32_t hash, uint64_t data); -- --static inline uint32_t hash_add_words(uint32_t, const uint32_t *, size_t); --static inline uint32_t hash_add_words64(uint32_t, const uint64_t *, size_t); --static inline uint32_t hash_add_bytes32(uint32_t, const uint32_t *, size_t); --static inline uint32_t hash_add_bytes64(uint32_t, const uint64_t *, size_t); -- --#if (defined(__ARM_FEATURE_CRC32) && defined(__aarch64__)) --#include "hash-aarch64.h" -- --#elif !(defined(__SSE4_2__) && defined(__x86_64__)) --/* Mhash-based implementation. */ -- --static inline uint32_t hash_add(uint32_t hash, uint32_t data) --{ -- return mhash_add(hash, data); --} -- --static inline uint32_t hash_add64(uint32_t hash, uint64_t data) --{ -- return hash_add(hash_add(hash, data), data >> 32); --} -- --static inline uint32_t hash_finish(uint32_t hash, uint32_t final) --{ -- return mhash_finish(hash ^ final); --} -- --/* Returns the hash of the 'n' 32-bit words at 'p', starting from 'basis'. -- * 'p' must be properly aligned. -- * -- * This is inlined for the compiler to have access to the 'n_words', which -- * in many cases is a constant. */ --static inline uint32_t --hash_words_inline(const uint32_t *p, size_t n_words, uint32_t basis) --{ -- return hash_finish(hash_add_words(basis, p, n_words), n_words * 4); --} -- --static inline uint32_t --hash_words64_inline(const uint64_t *p, size_t n_words, uint32_t basis) --{ -- return hash_finish(hash_add_words64(basis, p, n_words), n_words * 8); --} -- --static inline uint32_t hash_pointer(const void *p, uint32_t basis) --{ -- /* Often pointers are hashed simply by casting to integer type, but that -- * has pitfalls since the lower bits of a pointer are often all 0 for -- * alignment reasons. It's hard to guess where the entropy really is, so -- * we give up here and just use a high-quality hash function. -- * -- * The double cast suppresses a warning on 64-bit systems about casting to -- * an integer to different size. That's OK in this case, since most of the -- * entropy in the pointer is almost certainly in the lower 32 bits. */ -- return hash_int((uint32_t) (uintptr_t) p, basis); --} -- --static inline uint32_t hash_2words(uint32_t x, uint32_t y) --{ -- return hash_finish(hash_add(hash_add(x, 0), y), 8); --} -- --static inline uint32_t hash_uint64_basis(const uint64_t x, -- const uint32_t basis) --{ -- return hash_finish(hash_add64(basis, x), 8); --} -- --static inline uint32_t hash_uint64(const uint64_t x) --{ -- return hash_uint64_basis(x, 0); --} -- --#else /* __SSE4_2__ && __x86_64__ */ --#include -- --static inline uint32_t hash_add(uint32_t hash, uint32_t data) --{ -- return _mm_crc32_u32(hash, data); --} -- --/* Add the halves of 'data' in the memory order. */ --static inline uint32_t hash_add64(uint32_t hash, uint64_t data) --{ -- return _mm_crc32_u64(hash, data); --} -- --static inline uint32_t hash_finish(uint64_t hash, uint64_t final) --{ -- /* The finishing multiplier 0x805204f3 has been experimentally -- * derived to pass the testsuite hash tests. */ -- hash = _mm_crc32_u64(hash, final) * 0x805204f3; -- return hash ^ (uint32_t)hash >> 16; /* Increase entropy in LSBs. */ --} -- --/* Returns the hash of the 'n' 32-bit words at 'p_', starting from 'basis'. -- * We access 'p_' as a uint64_t pointer, which is fine for __SSE_4_2__. -- * -- * This is inlined for the compiler to have access to the 'n_words', which -- * in many cases is a constant. */ --static inline uint32_t --hash_words_inline(const uint32_t p_[], size_t n_words, uint32_t basis) --{ -- const uint64_t *p = (const void *)p_; -- uint64_t hash1 = basis; -- uint64_t hash2 = 0; -- uint64_t hash3 = n_words; -- const uint32_t *endp = (const uint32_t *)p + n_words; -- const uint64_t *limit = p + n_words / 2 - 3; -- -- while (p <= limit) { -- hash1 = _mm_crc32_u64(hash1, p[0]); -- hash2 = _mm_crc32_u64(hash2, p[1]); -- hash3 = _mm_crc32_u64(hash3, p[2]); -- p += 3; -- } -- switch (endp - (const uint32_t *)p) { -- case 1: -- hash1 = _mm_crc32_u32(hash1, *(const uint32_t *)&p[0]); -- break; -- case 2: -- hash1 = _mm_crc32_u64(hash1, p[0]); -- break; -- case 3: -- hash1 = _mm_crc32_u64(hash1, p[0]); -- hash2 = _mm_crc32_u32(hash2, *(const uint32_t *)&p[1]); -- break; -- case 4: -- hash1 = _mm_crc32_u64(hash1, p[0]); -- hash2 = _mm_crc32_u64(hash2, p[1]); -- break; -- case 5: -- hash1 = _mm_crc32_u64(hash1, p[0]); -- hash2 = _mm_crc32_u64(hash2, p[1]); -- hash3 = _mm_crc32_u32(hash3, *(const uint32_t *)&p[2]); -- break; -- } -- return hash_finish(hash1, hash2 << 32 | hash3); --} -- --/* A simpler version for 64-bit data. -- * 'n_words' is the count of 64-bit words, basis is 64 bits. */ --static inline uint32_t --hash_words64_inline(const uint64_t *p, size_t n_words, uint32_t basis) --{ -- uint64_t hash1 = basis; -- uint64_t hash2 = 0; -- uint64_t hash3 = n_words; -- const uint64_t *endp = p + n_words; -- const uint64_t *limit = endp - 3; -- -- while (p <= limit) { -- hash1 = _mm_crc32_u64(hash1, p[0]); -- hash2 = _mm_crc32_u64(hash2, p[1]); -- hash3 = _mm_crc32_u64(hash3, p[2]); -- p += 3; -- } -- switch (endp - p) { -- case 1: -- hash1 = _mm_crc32_u64(hash1, p[0]); -- break; -- case 2: -- hash1 = _mm_crc32_u64(hash1, p[0]); -- hash2 = _mm_crc32_u64(hash2, p[1]); -- break; -- } -- return hash_finish(hash1, hash2 << 32 | hash3); --} -- --static inline uint32_t hash_uint64_basis(const uint64_t x, -- const uint32_t basis) --{ -- /* '23' chosen to mix bits enough for the test-hash to pass. */ -- return hash_finish(hash_add64(basis, x), 23); --} -- --static inline uint32_t hash_uint64(const uint64_t x) --{ -- return hash_uint64_basis(x, 0); --} -- --static inline uint32_t hash_2words(uint32_t x, uint32_t y) --{ -- return hash_uint64((uint64_t)y << 32 | x); --} -- --static inline uint32_t hash_pointer(const void *p, uint32_t basis) --{ -- return hash_uint64_basis((uint64_t) (uintptr_t) p, basis); --} --#endif -- --uint32_t hash_words__(const uint32_t *p, size_t n_words, uint32_t basis); --uint32_t hash_words64__(const uint64_t *p, size_t n_words, uint32_t basis); -- --/* Inline the larger hash functions only when 'n_words' is known to be -- * compile-time constant. */ --#if __GNUC__ >= 4 --static inline uint32_t --hash_words(const uint32_t *p, size_t n_words, uint32_t basis) --{ -- if (__builtin_constant_p(n_words)) { -- return hash_words_inline(p, n_words, basis); -- } else { -- return hash_words__(p, n_words, basis); -- } --} -- --static inline uint32_t --hash_words64(const uint64_t *p, size_t n_words, uint32_t basis) --{ -- if (__builtin_constant_p(n_words)) { -- return hash_words64_inline(p, n_words, basis); -- } else { -- return hash_words64__(p, n_words, basis); -- } --} -- --#else -- --static inline uint32_t --hash_words(const uint32_t *p, size_t n_words, uint32_t basis) --{ -- return hash_words__(p, n_words, basis); --} -- --static inline uint32_t --hash_words64(const uint64_t *p, size_t n_words, uint32_t basis) --{ -- return hash_words64__(p, n_words, basis); --} --#endif -- --static inline uint32_t --hash_bytes32(const uint32_t *p, size_t n_bytes, uint32_t basis) --{ -- return hash_words(p, n_bytes / 4, basis); --} -- --static inline uint32_t --hash_bytes64(const uint64_t *p, size_t n_bytes, uint32_t basis) --{ -- return hash_words64(p, n_bytes / 8, basis); --} -- --static inline uint32_t hash_string(const char *s, uint32_t basis) --{ -- return hash_bytes(s, strlen(s), basis); --} -- --static inline uint32_t hash_int(uint32_t x, uint32_t basis) --{ -- return hash_2words(x, basis); --} -- --/* An attempt at a useful 1-bit hash function. Has not been analyzed for -- * quality. */ --static inline uint32_t hash_boolean(bool x, uint32_t basis) --{ -- const uint32_t P0 = 0xc2b73583; /* This is hash_int(1, 0). */ -- const uint32_t P1 = 0xe90f1258; /* This is hash_int(2, 0). */ -- return (x ? P0 : P1) ^ hash_rot(basis, 1); --} -- --/* Helper functions for calling hash_add() for several 32- or 64-bit words in a -- * buffer. These are not hash functions by themselves, since they need -- * hash_finish() to be called, so if you are looking for a full hash function -- * see hash_words(), etc. */ -- --static inline uint32_t --hash_add_words(uint32_t hash, const uint32_t *p, size_t n_words) --{ -- for (size_t i = 0; i < n_words; i++) { -- hash = hash_add(hash, p[i]); -- } -- return hash; --} -- --static inline uint32_t --hash_add_words64(uint32_t hash, const uint64_t *p, size_t n_words) --{ -- for (size_t i = 0; i < n_words; i++) { -- hash = hash_add64(hash, p[i]); -- } -- return hash; --} -- --static inline uint32_t --hash_add_bytes32(uint32_t hash, const uint32_t *p, size_t n_bytes) --{ -- return hash_add_words(hash, p, n_bytes / 4); --} -- --static inline uint32_t --hash_add_bytes64(uint32_t hash, const uint64_t *p, size_t n_bytes) --{ -- return hash_add_words64(hash, p, n_bytes / 8); --} -- --#ifdef __cplusplus --} --#endif -- --#endif /* hash.h */ -Index: openvswitch-2.17.2/include/internal/hash.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/hash.h -@@ -0,0 +1,398 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2012, 2013, 2014, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+#ifndef HASH_H -+#define HASH_H 1 -+ -+#include -+#include -+#include -+#include -+#include "internal/util.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+static inline uint32_t -+hash_rot(uint32_t x, int k) -+{ -+ return (x << k) | (x >> (32 - k)); -+} -+ -+uint32_t hash_bytes(const void *, size_t n_bytes, uint32_t basis); -+/* The hash input must be a word larger than 128 bits. */ -+void hash_bytes128(const void *_, size_t n_bytes, uint32_t basis, -+ ovs_u128 *out); -+ -+static inline uint32_t hash_int(uint32_t x, uint32_t basis); -+static inline uint32_t hash_2words(uint32_t, uint32_t); -+static inline uint32_t hash_uint64(const uint64_t); -+static inline uint32_t hash_uint64_basis(const uint64_t x, -+ const uint32_t basis); -+uint32_t hash_3words(uint32_t, uint32_t, uint32_t); -+ -+static inline uint32_t hash_boolean(bool x, uint32_t basis); -+uint32_t hash_double(double, uint32_t basis); -+ -+static inline uint32_t hash_pointer(const void *, uint32_t basis); -+static inline uint32_t hash_string(const char *, uint32_t basis); -+ -+/* Murmurhash by Austin Appleby, -+ * from https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp -+ * -+ * The upstream license there says: -+ * -+ * MurmurHash3 was written by Austin Appleby, and is placed in the public -+ * domain. The author hereby disclaims copyright to this source code. -+ * -+ * See hash_words() for sample usage. */ -+ -+static inline uint32_t mhash_add__(uint32_t hash, uint32_t data) -+{ -+ /* zero-valued 'data' will not change the 'hash' value */ -+ if (!data) { -+ return hash; -+ } -+ -+ data *= 0xcc9e2d51; -+ data = hash_rot(data, 15); -+ data *= 0x1b873593; -+ return hash ^ data; -+} -+ -+static inline uint32_t mhash_add(uint32_t hash, uint32_t data) -+{ -+ hash = mhash_add__(hash, data); -+ hash = hash_rot(hash, 13); -+ return hash * 5 + 0xe6546b64; -+} -+ -+static inline uint32_t mhash_finish(uint32_t hash) -+{ -+ hash ^= hash >> 16; -+ hash *= 0x85ebca6b; -+ hash ^= hash >> 13; -+ hash *= 0xc2b2ae35; -+ hash ^= hash >> 16; -+ return hash; -+} -+ -+static inline uint32_t hash_add(uint32_t hash, uint32_t data); -+static inline uint32_t hash_add64(uint32_t hash, uint64_t data); -+ -+static inline uint32_t hash_add_words(uint32_t, const uint32_t *, size_t); -+static inline uint32_t hash_add_words64(uint32_t, const uint64_t *, size_t); -+static inline uint32_t hash_add_bytes32(uint32_t, const uint32_t *, size_t); -+static inline uint32_t hash_add_bytes64(uint32_t, const uint64_t *, size_t); -+ -+#if (defined(__ARM_FEATURE_CRC32) && defined(__aarch64__)) -+#include "internal/hash-aarch64.h" -+ -+#elif !(defined(__SSE4_2__) && defined(__x86_64__)) -+/* Mhash-based implementation. */ -+ -+static inline uint32_t hash_add(uint32_t hash, uint32_t data) -+{ -+ return mhash_add(hash, data); -+} -+ -+static inline uint32_t hash_add64(uint32_t hash, uint64_t data) -+{ -+ return hash_add(hash_add(hash, data), data >> 32); -+} -+ -+static inline uint32_t hash_finish(uint32_t hash, uint32_t final) -+{ -+ return mhash_finish(hash ^ final); -+} -+ -+/* Returns the hash of the 'n' 32-bit words at 'p', starting from 'basis'. -+ * 'p' must be properly aligned. -+ * -+ * This is inlined for the compiler to have access to the 'n_words', which -+ * in many cases is a constant. */ -+static inline uint32_t -+hash_words_inline(const uint32_t *p, size_t n_words, uint32_t basis) -+{ -+ return hash_finish(hash_add_words(basis, p, n_words), n_words * 4); -+} -+ -+static inline uint32_t -+hash_words64_inline(const uint64_t *p, size_t n_words, uint32_t basis) -+{ -+ return hash_finish(hash_add_words64(basis, p, n_words), n_words * 8); -+} -+ -+static inline uint32_t hash_pointer(const void *p, uint32_t basis) -+{ -+ /* Often pointers are hashed simply by casting to integer type, but that -+ * has pitfalls since the lower bits of a pointer are often all 0 for -+ * alignment reasons. It's hard to guess where the entropy really is, so -+ * we give up here and just use a high-quality hash function. -+ * -+ * The double cast suppresses a warning on 64-bit systems about casting to -+ * an integer to different size. That's OK in this case, since most of the -+ * entropy in the pointer is almost certainly in the lower 32 bits. */ -+ return hash_int((uint32_t) (uintptr_t) p, basis); -+} -+ -+static inline uint32_t hash_2words(uint32_t x, uint32_t y) -+{ -+ return hash_finish(hash_add(hash_add(x, 0), y), 8); -+} -+ -+static inline uint32_t hash_uint64_basis(const uint64_t x, -+ const uint32_t basis) -+{ -+ return hash_finish(hash_add64(basis, x), 8); -+} -+ -+static inline uint32_t hash_uint64(const uint64_t x) -+{ -+ return hash_uint64_basis(x, 0); -+} -+ -+#else /* __SSE4_2__ && __x86_64__ */ -+#include -+ -+static inline uint32_t hash_add(uint32_t hash, uint32_t data) -+{ -+ return _mm_crc32_u32(hash, data); -+} -+ -+/* Add the halves of 'data' in the memory order. */ -+static inline uint32_t hash_add64(uint32_t hash, uint64_t data) -+{ -+ return _mm_crc32_u64(hash, data); -+} -+ -+static inline uint32_t hash_finish(uint64_t hash, uint64_t final) -+{ -+ /* The finishing multiplier 0x805204f3 has been experimentally -+ * derived to pass the testsuite hash tests. */ -+ hash = _mm_crc32_u64(hash, final) * 0x805204f3; -+ return hash ^ (uint32_t)hash >> 16; /* Increase entropy in LSBs. */ -+} -+ -+/* Returns the hash of the 'n' 32-bit words at 'p_', starting from 'basis'. -+ * We access 'p_' as a uint64_t pointer, which is fine for __SSE_4_2__. -+ * -+ * This is inlined for the compiler to have access to the 'n_words', which -+ * in many cases is a constant. */ -+static inline uint32_t -+hash_words_inline(const uint32_t p_[], size_t n_words, uint32_t basis) -+{ -+ const uint64_t *p = (const void *)p_; -+ uint64_t hash1 = basis; -+ uint64_t hash2 = 0; -+ uint64_t hash3 = n_words; -+ const uint32_t *endp = (const uint32_t *)p + n_words; -+ const uint64_t *limit = p + n_words / 2 - 3; -+ -+ while (p <= limit) { -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ hash2 = _mm_crc32_u64(hash2, p[1]); -+ hash3 = _mm_crc32_u64(hash3, p[2]); -+ p += 3; -+ } -+ switch (endp - (const uint32_t *)p) { -+ case 1: -+ hash1 = _mm_crc32_u32(hash1, *(const uint32_t *)&p[0]); -+ break; -+ case 2: -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ break; -+ case 3: -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ hash2 = _mm_crc32_u32(hash2, *(const uint32_t *)&p[1]); -+ break; -+ case 4: -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ hash2 = _mm_crc32_u64(hash2, p[1]); -+ break; -+ case 5: -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ hash2 = _mm_crc32_u64(hash2, p[1]); -+ hash3 = _mm_crc32_u32(hash3, *(const uint32_t *)&p[2]); -+ break; -+ } -+ return hash_finish(hash1, hash2 << 32 | hash3); -+} -+ -+/* A simpler version for 64-bit data. -+ * 'n_words' is the count of 64-bit words, basis is 64 bits. */ -+static inline uint32_t -+hash_words64_inline(const uint64_t *p, size_t n_words, uint32_t basis) -+{ -+ uint64_t hash1 = basis; -+ uint64_t hash2 = 0; -+ uint64_t hash3 = n_words; -+ const uint64_t *endp = p + n_words; -+ const uint64_t *limit = endp - 3; -+ -+ while (p <= limit) { -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ hash2 = _mm_crc32_u64(hash2, p[1]); -+ hash3 = _mm_crc32_u64(hash3, p[2]); -+ p += 3; -+ } -+ switch (endp - p) { -+ case 1: -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ break; -+ case 2: -+ hash1 = _mm_crc32_u64(hash1, p[0]); -+ hash2 = _mm_crc32_u64(hash2, p[1]); -+ break; -+ } -+ return hash_finish(hash1, hash2 << 32 | hash3); -+} -+ -+static inline uint32_t hash_uint64_basis(const uint64_t x, -+ const uint32_t basis) -+{ -+ /* '23' chosen to mix bits enough for the test-hash to pass. */ -+ return hash_finish(hash_add64(basis, x), 23); -+} -+ -+static inline uint32_t hash_uint64(const uint64_t x) -+{ -+ return hash_uint64_basis(x, 0); -+} -+ -+static inline uint32_t hash_2words(uint32_t x, uint32_t y) -+{ -+ return hash_uint64((uint64_t)y << 32 | x); -+} -+ -+static inline uint32_t hash_pointer(const void *p, uint32_t basis) -+{ -+ return hash_uint64_basis((uint64_t) (uintptr_t) p, basis); -+} -+#endif -+ -+uint32_t hash_words__(const uint32_t *p, size_t n_words, uint32_t basis); -+uint32_t hash_words64__(const uint64_t *p, size_t n_words, uint32_t basis); -+ -+/* Inline the larger hash functions only when 'n_words' is known to be -+ * compile-time constant. */ -+#if __GNUC__ >= 4 -+static inline uint32_t -+hash_words(const uint32_t *p, size_t n_words, uint32_t basis) -+{ -+ if (__builtin_constant_p(n_words)) { -+ return hash_words_inline(p, n_words, basis); -+ } else { -+ return hash_words__(p, n_words, basis); -+ } -+} -+ -+static inline uint32_t -+hash_words64(const uint64_t *p, size_t n_words, uint32_t basis) -+{ -+ if (__builtin_constant_p(n_words)) { -+ return hash_words64_inline(p, n_words, basis); -+ } else { -+ return hash_words64__(p, n_words, basis); -+ } -+} -+ -+#else -+ -+static inline uint32_t -+hash_words(const uint32_t *p, size_t n_words, uint32_t basis) -+{ -+ return hash_words__(p, n_words, basis); -+} -+ -+static inline uint32_t -+hash_words64(const uint64_t *p, size_t n_words, uint32_t basis) -+{ -+ return hash_words64__(p, n_words, basis); -+} -+#endif -+ -+static inline uint32_t -+hash_bytes32(const uint32_t *p, size_t n_bytes, uint32_t basis) -+{ -+ return hash_words(p, n_bytes / 4, basis); -+} -+ -+static inline uint32_t -+hash_bytes64(const uint64_t *p, size_t n_bytes, uint32_t basis) -+{ -+ return hash_words64(p, n_bytes / 8, basis); -+} -+ -+static inline uint32_t hash_string(const char *s, uint32_t basis) -+{ -+ return hash_bytes(s, strlen(s), basis); -+} -+ -+static inline uint32_t hash_int(uint32_t x, uint32_t basis) -+{ -+ return hash_2words(x, basis); -+} -+ -+/* An attempt at a useful 1-bit hash function. Has not been analyzed for -+ * quality. */ -+static inline uint32_t hash_boolean(bool x, uint32_t basis) -+{ -+ const uint32_t P0 = 0xc2b73583; /* This is hash_int(1, 0). */ -+ const uint32_t P1 = 0xe90f1258; /* This is hash_int(2, 0). */ -+ return (x ? P0 : P1) ^ hash_rot(basis, 1); -+} -+ -+/* Helper functions for calling hash_add() for several 32- or 64-bit words in a -+ * buffer. These are not hash functions by themselves, since they need -+ * hash_finish() to be called, so if you are looking for a full hash function -+ * see hash_words(), etc. */ -+ -+static inline uint32_t -+hash_add_words(uint32_t hash, const uint32_t *p, size_t n_words) -+{ -+ for (size_t i = 0; i < n_words; i++) { -+ hash = hash_add(hash, p[i]); -+ } -+ return hash; -+} -+ -+static inline uint32_t -+hash_add_words64(uint32_t hash, const uint64_t *p, size_t n_words) -+{ -+ for (size_t i = 0; i < n_words; i++) { -+ hash = hash_add64(hash, p[i]); -+ } -+ return hash; -+} -+ -+static inline uint32_t -+hash_add_bytes32(uint32_t hash, const uint32_t *p, size_t n_bytes) -+{ -+ return hash_add_words(hash, p, n_bytes / 4); -+} -+ -+static inline uint32_t -+hash_add_bytes64(uint32_t hash, const uint64_t *p, size_t n_bytes) -+{ -+ return hash_add_words64(hash, p, n_bytes / 8); -+} -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* hash.h */ -Index: openvswitch-2.17.2/lib/hindex.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/hindex.h -+++ /dev/null -@@ -1,222 +0,0 @@ --/* -- * Copyright (c) 2013, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef HINDEX_H --#define HINDEX_H 1 -- --/* Hashed multimap. -- * -- * hindex is a hash table data structure that gracefully handles duplicates. -- * With a high-quality hash function, insertion, deletion, and search are O(1) -- * expected time, regardless of the number of duplicates for a given key. */ -- --#include --#include --#include "util.h" -- --/* A hash index node, to embed inside the data structure being indexed. -- * -- * Nodes are linked together like this (the boxes are labeled with hash -- * values): -- * -- * +--------+ d +--------+ d +--------+ d -- * bucket---> | 6 |---->| 20 |---->| 15 |---->null -- * +-|------+ +-|------+ +-|------+ -- * | ^ | | ^ -- * s| |d |s s| |d -- * V | V V | -- * +------|-+ null +------|-+ -- * | 6 | | 15 | -- * +-|------+ +-|------+ -- * | ^ | -- * s| |d s| -- * V | V -- * +------|-+ null -- * | 6 | -- * +-|------+ -- * | -- * s| -- * V -- * null -- * -- * The basic usage is: -- * -- * - To visit the unique hash values in the hindex, follow the 'd' -- * ("different") pointers starting from each bucket. The nodes visited -- * this way are called "head" nodes, because they are at the head of the -- * vertical chains. -- * -- * - To visit the nodes with hash value H, follow the 'd' pointers in the -- * appropriate bucket until you find one with hash H, then follow the 's' -- * ("same") pointers until you hit a null pointer. The non-head nodes -- * visited this way are called "body" nodes. -- * -- * - The 'd' pointers in body nodes point back to the previous body node -- * or, for the first body node, to the head node. (This makes it -- * possible to remove a body node without traversing all the way downward -- * from the head). -- */ --struct hindex_node { -- /* Hash value. */ -- size_t hash; -- -- /* In a head node, the next head node (with a hash different from this -- * node), or NULL if this is the last node in this bucket. -- * -- * In a body node, the previous head or body node (with the same hash as -- * this node). Never null. */ -- struct hindex_node *d; -- -- /* In a head or a body node, the next body node with the same hash as this -- * node. NULL if this is the last node with this hash. */ -- struct hindex_node *s; --}; -- --/* A hash index. */ --struct hindex { -- struct hindex_node **buckets; /* Must point to 'one' iff 'mask' == 0. */ -- struct hindex_node *one; -- size_t mask; /* 0 or more lowest-order bits set, others cleared. */ -- size_t n_unique; /* Number of unique hashes (the number of head nodes). */ --}; -- --/* Initializer for an empty hash index. */ --#define HINDEX_INITIALIZER(HINDEX) \ -- { (struct hindex_node **const) &(HINDEX)->one, NULL, 0, 0 } -- --/* Initialization. */ --void hindex_init(struct hindex *); --void hindex_destroy(struct hindex *); --void hindex_clear(struct hindex *); --void hindex_swap(struct hindex *a, struct hindex *b); --void hindex_moved(struct hindex *hindex); --static inline bool hindex_is_empty(const struct hindex *); -- --/* Adjusting capacity. */ --void hindex_expand(struct hindex *); --void hindex_shrink(struct hindex *); --void hindex_reserve(struct hindex *, size_t capacity); -- --/* Insertion and deletion. */ --void hindex_insert_fast(struct hindex *, struct hindex_node *, size_t hash); --void hindex_insert(struct hindex *, struct hindex_node *, size_t hash); --void hindex_remove(struct hindex *, struct hindex_node *); -- --/* Search. -- * -- * HINDEX_FOR_EACH_WITH_HASH iterates NODE over all of the nodes in HINDEX that -- * have hash value equal to HASH. MEMBER must be the name of the 'struct -- * hindex_node' member within NODE. -- * -- * The loop should not change NODE to point to a different node or insert or -- * delete nodes in HINDEX (unless it "break"s out of the loop to terminate -- * iteration). -- * -- * Evaluates HASH only once. -- */ --#define HINDEX_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HINDEX) \ -- for (INIT_MULTIVAR(NODE, MEMBER, hindex_node_with_hash(HINDEX, HASH), \ -- struct hindex_node); \ -- CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -- UPDATE_MULTIVAR(NODE, ITER_VAR(NODE)->s)) -- --/* Safe when NODE may be freed (not needed when NODE may be removed from the -- * hash map but its members remain accessible and intact). */ --#define HINDEX_FOR_EACH_WITH_HASH_SAFE_LONG(NODE, NEXT, MEMBER, HASH, HINDEX) \ -- for (INIT_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ -- hindex_node_with_hash(HINDEX, HASH), \ -- struct hindex_node); \ -- CONDITION_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ -- ITER_VAR(NODE) != NULL, \ -- ITER_VAR(NEXT) = ITER_VAR(NODE)->s, \ -- ITER_VAR(NEXT) != NULL); \ -- UPDATE_MULTIVAR_SAFE_LONG(NODE, NEXT)) -- --/* Short version of HINDEX_FOR_EACH_WITH_HASH_SAFE. */ --#define HINDEX_FOR_EACH_WITH_HASH_SAFE_SHORT(NODE, MEMBER, HASH, HINDEX) \ -- for (INIT_MULTIVAR_SAFE_SHORT(NODE, MEMBER, \ -- hindex_node_with_hash(HINDEX, HASH), \ -- struct hindex_node); \ -- CONDITION_MULTIVAR_SAFE_SHORT(NODE, MEMBER, \ -- ITER_VAR(NODE) != NULL, \ -- ITER_NEXT_VAR(NODE) = ITER_VAR(NODE)->s); \ -- UPDATE_MULTIVAR_SAFE_SHORT(NODE)) -- --#define HINDEX_FOR_EACH_WITH_HASH_SAFE(...) \ -- OVERLOAD_SAFE_MACRO(HINDEX_FOR_EACH_WITH_HASH_SAFE_LONG, \ -- HINDEX_FOR_EACH_WITH_HASH_SAFE_SHORT, \ -- 5, __VA_ARGS__) -- -- --/* Returns the head node in 'hindex' with the given 'hash', or a null pointer -- * if no nodes have that hash value. */ --static inline struct hindex_node * --hindex_node_with_hash(const struct hindex *hindex, size_t hash) --{ -- struct hindex_node *node = hindex->buckets[hash & hindex->mask]; -- -- while (node && node->hash != hash) { -- node = node->d; -- } -- return node; --} -- --/* Iteration. */ -- --/* Iterates through every node in HINDEX. */ --#define HINDEX_FOR_EACH(NODE, MEMBER, HINDEX) \ -- for (INIT_MULTIVAR(NODE, MEMBER, hindex_first(HINDEX), \ -- struct hindex_node); \ -- CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -- UPDATE_MULTIVAR(NODE, hindex_next(HINDEX, ITER_VAR(NODE)))) -- --/* Safe when NODE may be freed (not needed when NODE may be removed from the -- * hash index but its members remain accessible and intact). */ --#define HINDEX_FOR_EACH_SAFE_LONG(NODE, NEXT, MEMBER, HINDEX) \ -- for (INIT_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, hindex_first(HINDEX), \ -- struct hindex_node); \ -- CONDITION_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ -- ITER_VAR(NODE) != NULL, \ -- ITER_VAR(NEXT) = hindex_next(HINDEX, ITER_VAR(NODE)), \ -- ITER_VAR(NEXT) != NULL); \ -- UPDATE_MULTIVAR_SAFE_LONG(NODE, NEXT)) -- --/* Short version of HINDEX_FOR_EACH_SAFE. */ --#define HINDEX_FOR_EACH_SAFE_SHORT(NODE, MEMBER, HINDEX) \ -- for (INIT_MULTIVAR_SAFE_SHORT(NODE, MEMBER, hindex_first(HINDEX), \ -- struct hindex_node); \ -- CONDITION_MULTIVAR_SAFE_SHORT(NODE, MEMBER, \ -- ITER_VAR(NODE) != NULL, \ -- ITER_NEXT_VAR(NODE) = hindex_next(HINDEX, ITER_VAR(NODE))); \ -- UPDATE_MULTIVAR_SAFE_SHORT(NODE)) -- --#define HINDEX_FOR_EACH_SAFE(...) \ -- OVERLOAD_SAFE_MACRO(HINDEX_FOR_EACH_SAFE_LONG, \ -- HINDEX_FOR_EACH_SAFE_SHORT, \ -- 4, __VA_ARGS__) -- --struct hindex_node *hindex_first(const struct hindex *); --struct hindex_node *hindex_next(const struct hindex *, -- const struct hindex_node *); -- --/* Returns true if 'hindex' currently contains no nodes, false otherwise. */ --static inline bool --hindex_is_empty(const struct hindex *hindex) --{ -- return hindex->n_unique == 0; --} -- --#endif /* hindex.h */ -Index: openvswitch-2.17.2/include/internal/hindex.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/hindex.h -@@ -0,0 +1,222 @@ -+/* -+ * Copyright (c) 2013, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef HINDEX_H -+#define HINDEX_H 1 -+ -+/* Hashed multimap. -+ * -+ * hindex is a hash table data structure that gracefully handles duplicates. -+ * With a high-quality hash function, insertion, deletion, and search are O(1) -+ * expected time, regardless of the number of duplicates for a given key. */ -+ -+#include -+#include -+#include "internal/util.h" -+ -+/* A hash index node, to embed inside the data structure being indexed. -+ * -+ * Nodes are linked together like this (the boxes are labeled with hash -+ * values): -+ * -+ * +--------+ d +--------+ d +--------+ d -+ * bucket---> | 6 |---->| 20 |---->| 15 |---->null -+ * +-|------+ +-|------+ +-|------+ -+ * | ^ | | ^ -+ * s| |d |s s| |d -+ * V | V V | -+ * +------|-+ null +------|-+ -+ * | 6 | | 15 | -+ * +-|------+ +-|------+ -+ * | ^ | -+ * s| |d s| -+ * V | V -+ * +------|-+ null -+ * | 6 | -+ * +-|------+ -+ * | -+ * s| -+ * V -+ * null -+ * -+ * The basic usage is: -+ * -+ * - To visit the unique hash values in the hindex, follow the 'd' -+ * ("different") pointers starting from each bucket. The nodes visited -+ * this way are called "head" nodes, because they are at the head of the -+ * vertical chains. -+ * -+ * - To visit the nodes with hash value H, follow the 'd' pointers in the -+ * appropriate bucket until you find one with hash H, then follow the 's' -+ * ("same") pointers until you hit a null pointer. The non-head nodes -+ * visited this way are called "body" nodes. -+ * -+ * - The 'd' pointers in body nodes point back to the previous body node -+ * or, for the first body node, to the head node. (This makes it -+ * possible to remove a body node without traversing all the way downward -+ * from the head). -+ */ -+struct hindex_node { -+ /* Hash value. */ -+ size_t hash; -+ -+ /* In a head node, the next head node (with a hash different from this -+ * node), or NULL if this is the last node in this bucket. -+ * -+ * In a body node, the previous head or body node (with the same hash as -+ * this node). Never null. */ -+ struct hindex_node *d; -+ -+ /* In a head or a body node, the next body node with the same hash as this -+ * node. NULL if this is the last node with this hash. */ -+ struct hindex_node *s; -+}; -+ -+/* A hash index. */ -+struct hindex { -+ struct hindex_node **buckets; /* Must point to 'one' iff 'mask' == 0. */ -+ struct hindex_node *one; -+ size_t mask; /* 0 or more lowest-order bits set, others cleared. */ -+ size_t n_unique; /* Number of unique hashes (the number of head nodes). */ -+}; -+ -+/* Initializer for an empty hash index. */ -+#define HINDEX_INITIALIZER(HINDEX) \ -+ { (struct hindex_node **const) &(HINDEX)->one, NULL, 0, 0 } -+ -+/* Initialization. */ -+void hindex_init(struct hindex *); -+void hindex_destroy(struct hindex *); -+void hindex_clear(struct hindex *); -+void hindex_swap(struct hindex *a, struct hindex *b); -+void hindex_moved(struct hindex *hindex); -+static inline bool hindex_is_empty(const struct hindex *); -+ -+/* Adjusting capacity. */ -+void hindex_expand(struct hindex *); -+void hindex_shrink(struct hindex *); -+void hindex_reserve(struct hindex *, size_t capacity); -+ -+/* Insertion and deletion. */ -+void hindex_insert_fast(struct hindex *, struct hindex_node *, size_t hash); -+void hindex_insert(struct hindex *, struct hindex_node *, size_t hash); -+void hindex_remove(struct hindex *, struct hindex_node *); -+ -+/* Search. -+ * -+ * HINDEX_FOR_EACH_WITH_HASH iterates NODE over all of the nodes in HINDEX that -+ * have hash value equal to HASH. MEMBER must be the name of the 'struct -+ * hindex_node' member within NODE. -+ * -+ * The loop should not change NODE to point to a different node or insert or -+ * delete nodes in HINDEX (unless it "break"s out of the loop to terminate -+ * iteration). -+ * -+ * Evaluates HASH only once. -+ */ -+#define HINDEX_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HINDEX) \ -+ for (INIT_MULTIVAR(NODE, MEMBER, hindex_node_with_hash(HINDEX, HASH), \ -+ struct hindex_node); \ -+ CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -+ UPDATE_MULTIVAR(NODE, ITER_VAR(NODE)->s)) -+ -+/* Safe when NODE may be freed (not needed when NODE may be removed from the -+ * hash map but its members remain accessible and intact). */ -+#define HINDEX_FOR_EACH_WITH_HASH_SAFE_LONG(NODE, NEXT, MEMBER, HASH, HINDEX) \ -+ for (INIT_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ -+ hindex_node_with_hash(HINDEX, HASH), \ -+ struct hindex_node); \ -+ CONDITION_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ -+ ITER_VAR(NODE) != NULL, \ -+ ITER_VAR(NEXT) = ITER_VAR(NODE)->s, \ -+ ITER_VAR(NEXT) != NULL); \ -+ UPDATE_MULTIVAR_SAFE_LONG(NODE, NEXT)) -+ -+/* Short version of HINDEX_FOR_EACH_WITH_HASH_SAFE. */ -+#define HINDEX_FOR_EACH_WITH_HASH_SAFE_SHORT(NODE, MEMBER, HASH, HINDEX) \ -+ for (INIT_MULTIVAR_SAFE_SHORT(NODE, MEMBER, \ -+ hindex_node_with_hash(HINDEX, HASH), \ -+ struct hindex_node); \ -+ CONDITION_MULTIVAR_SAFE_SHORT(NODE, MEMBER, \ -+ ITER_VAR(NODE) != NULL, \ -+ ITER_NEXT_VAR(NODE) = ITER_VAR(NODE)->s); \ -+ UPDATE_MULTIVAR_SAFE_SHORT(NODE)) -+ -+#define HINDEX_FOR_EACH_WITH_HASH_SAFE(...) \ -+ OVERLOAD_SAFE_MACRO(HINDEX_FOR_EACH_WITH_HASH_SAFE_LONG, \ -+ HINDEX_FOR_EACH_WITH_HASH_SAFE_SHORT, \ -+ 5, __VA_ARGS__) -+ -+ -+/* Returns the head node in 'hindex' with the given 'hash', or a null pointer -+ * if no nodes have that hash value. */ -+static inline struct hindex_node * -+hindex_node_with_hash(const struct hindex *hindex, size_t hash) -+{ -+ struct hindex_node *node = hindex->buckets[hash & hindex->mask]; -+ -+ while (node && node->hash != hash) { -+ node = node->d; -+ } -+ return node; -+} -+ -+/* Iteration. */ -+ -+/* Iterates through every node in HINDEX. */ -+#define HINDEX_FOR_EACH(NODE, MEMBER, HINDEX) \ -+ for (INIT_MULTIVAR(NODE, MEMBER, hindex_first(HINDEX), \ -+ struct hindex_node); \ -+ CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ -+ UPDATE_MULTIVAR(NODE, hindex_next(HINDEX, ITER_VAR(NODE)))) -+ -+/* Safe when NODE may be freed (not needed when NODE may be removed from the -+ * hash index but its members remain accessible and intact). */ -+#define HINDEX_FOR_EACH_SAFE_LONG(NODE, NEXT, MEMBER, HINDEX) \ -+ for (INIT_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, hindex_first(HINDEX), \ -+ struct hindex_node); \ -+ CONDITION_MULTIVAR_SAFE_LONG(NODE, NEXT, MEMBER, \ -+ ITER_VAR(NODE) != NULL, \ -+ ITER_VAR(NEXT) = hindex_next(HINDEX, ITER_VAR(NODE)), \ -+ ITER_VAR(NEXT) != NULL); \ -+ UPDATE_MULTIVAR_SAFE_LONG(NODE, NEXT)) -+ -+/* Short version of HINDEX_FOR_EACH_SAFE. */ -+#define HINDEX_FOR_EACH_SAFE_SHORT(NODE, MEMBER, HINDEX) \ -+ for (INIT_MULTIVAR_SAFE_SHORT(NODE, MEMBER, hindex_first(HINDEX), \ -+ struct hindex_node); \ -+ CONDITION_MULTIVAR_SAFE_SHORT(NODE, MEMBER, \ -+ ITER_VAR(NODE) != NULL, \ -+ ITER_NEXT_VAR(NODE) = hindex_next(HINDEX, ITER_VAR(NODE))); \ -+ UPDATE_MULTIVAR_SAFE_SHORT(NODE)) -+ -+#define HINDEX_FOR_EACH_SAFE(...) \ -+ OVERLOAD_SAFE_MACRO(HINDEX_FOR_EACH_SAFE_LONG, \ -+ HINDEX_FOR_EACH_SAFE_SHORT, \ -+ 4, __VA_ARGS__) -+ -+struct hindex_node *hindex_first(const struct hindex *); -+struct hindex_node *hindex_next(const struct hindex *, -+ const struct hindex_node *); -+ -+/* Returns true if 'hindex' currently contains no nodes, false otherwise. */ -+static inline bool -+hindex_is_empty(const struct hindex *hindex) -+{ -+ return hindex->n_unique == 0; -+} -+ -+#endif /* hindex.h */ -Index: openvswitch-2.17.2/lib/latch.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/latch.h -+++ /dev/null -@@ -1,47 +0,0 @@ --/* -- * Copyright (c) 2013 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef LATCH_H --#define LATCH_H 1 -- --/* A thread-safe, signal-safe, pollable doorbell. -- * -- * This is a thin wrapper around a pipe that allows threads to notify each -- * other that an event has occurred in a signal-safe way */ -- --#include --#include "util.h" -- --struct latch { --#ifndef _WIN32 -- int fds[2]; --#else -- HANDLE wevent; -- bool is_set; --#endif --}; -- --void latch_init(struct latch *); --void latch_destroy(struct latch *); -- --bool latch_poll(struct latch *); --void latch_set(struct latch *); -- --bool latch_is_set(const struct latch *); --void latch_wait_at(const struct latch *, const char *where); --#define latch_wait(latch) latch_wait_at(latch, OVS_SOURCE_LOCATOR) -- --#endif /* latch.h */ -Index: openvswitch-2.17.2/include/internal/latch.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/latch.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (c) 2013 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef LATCH_H -+#define LATCH_H 1 -+ -+/* A thread-safe, signal-safe, pollable doorbell. -+ * -+ * This is a thin wrapper around a pipe that allows threads to notify each -+ * other that an event has occurred in a signal-safe way */ -+ -+#include -+#include "internal/util.h" -+ -+struct latch { -+#ifndef _WIN32 -+ int fds[2]; -+#else -+ HANDLE wevent; -+ bool is_set; -+#endif -+}; -+ -+void latch_init(struct latch *); -+void latch_destroy(struct latch *); -+ -+bool latch_poll(struct latch *); -+void latch_set(struct latch *); -+ -+bool latch_is_set(const struct latch *); -+void latch_wait_at(const struct latch *, const char *where); -+#define latch_wait(latch) latch_wait_at(latch, OVS_SOURCE_LOCATOR) -+ -+#endif /* latch.h */ -Index: openvswitch-2.17.2/lib/mcast-snooping.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/mcast-snooping.h -+++ /dev/null -@@ -1,219 +0,0 @@ --/* -- * Copyright (c) 2014 Red Hat, Inc. -- * -- * Based on mac-learning implementation. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef MCAST_SNOOPING_H --#define MCAST_SNOOPING_H 1 -- --#include --#include "dp-packet.h" --#include "openvswitch/hmap.h" --#include "openvswitch/list.h" --#include "ovs-atomic.h" --#include "ovs-thread.h" --#include "packets.h" --#include "timeval.h" -- --struct mcast_snooping; -- --/* Default maximum size of a mcast snooping table, in entries. */ --#define MCAST_DEFAULT_MAX_ENTRIES 2048 -- --/* Time, in seconds, before expiring a mcast_group due to inactivity. */ --#define MCAST_ENTRY_DEFAULT_IDLE_TIME 300 -- --/* Time, in seconds, before expiring a mrouter_port due to inactivity. */ --#define MCAST_MROUTER_PORT_IDLE_TIME 180 -- --/* Multicast group entry. -- * Guarded by owning 'mcast_snooping''s rwlock. */ --struct mcast_group { -- /* Node in parent struct mcast_snooping hmap. */ -- struct hmap_node hmap_node; -- -- /* Multicast group IPv6/IPv4 address. */ -- struct in6_addr addr; -- -- /* VLAN tag. */ -- uint16_t vlan; -- -- /* Node in parent struct mcast_snooping group_lru. */ -- struct ovs_list group_node OVS_GUARDED; -- -- /* Contains struct mcast_group_bundle (ports), least recently used -- * at the front, most recently used at the back. */ -- struct ovs_list bundle_lru OVS_GUARDED; --}; -- --/* The bundle associated to the multicast group. -- * Guarded by owning 'mcast_snooping''s rwlock. */ --struct mcast_group_bundle { -- /* Node in parent struct mcast_group bundle_lru list. */ -- struct ovs_list bundle_node OVS_GUARDED; -- -- /* When this node expires. */ -- time_t expires; -- -- /* Learned port. */ -- void *port OVS_GUARDED; --}; -- --/* The bundle connected to a multicast router. -- * Guarded by owning 'mcast_snooping''s rwlock. */ --struct mcast_mrouter_bundle { -- /* Node in parent struct mcast_group mrouter_lru list. */ -- struct ovs_list mrouter_node OVS_GUARDED; -- -- /* When this node expires. */ -- time_t expires; -- -- /* VLAN tag. */ -- uint16_t vlan; -- -- /* Learned port. */ -- void *port OVS_GUARDED; --}; -- --/* The bundle to send multicast traffic or Reports. -- * Guarded by owning 'mcast_snooping''s rwlock */ --struct mcast_port_bundle { -- /* Node in parent struct mcast_snooping. */ -- struct ovs_list node; -- -- /* VLAN tag. */ -- uint16_t vlan; -- -- /* Learned port. */ -- void *port; --}; -- --/* Multicast snooping table. */ --struct mcast_snooping { -- /* Snooping/learning table. */ -- struct hmap table; -- -- /* Contains struct mcast_group, least recently used at the front, -- * most recently used at the back. */ -- struct ovs_list group_lru OVS_GUARDED; -- -- /* Contains struct mcast_mrouter_bundle, least recently used at the -- * front, most recently used at the back. */ -- struct ovs_list mrouter_lru OVS_GUARDED; -- -- /* Contains struct mcast_port_bundle to be flooded with multicast -- * packets in no special order. */ -- struct ovs_list fport_list OVS_GUARDED; -- -- /* Contains struct mcast_port_bundle to forward Reports in -- * no special order. */ -- struct ovs_list rport_list OVS_GUARDED; -- -- /* Secret for randomizing hash table. */ -- uint32_t secret; -- -- /* Maximum age before deleting an entry. */ -- unsigned int idle_time; -- -- /* Maximum number of multicast groups learned. */ -- size_t max_entries; -- -- /* True if flow revalidation is needed. */ -- bool need_revalidate; -- -- /* True if unregistered multicast packets should be flooded to all -- * ports, otherwise send them to ports connected to multicast routers. */ -- bool flood_unreg; -- -- struct ovs_refcount ref_cnt; -- struct ovs_rwlock rwlock; --}; -- --/* Basics. */ --bool mcast_snooping_enabled(const struct mcast_snooping *ms); --bool mcast_snooping_flood_unreg(const struct mcast_snooping *ms); --int mcast_mrouter_age(const struct mcast_snooping *ms, -- const struct mcast_mrouter_bundle *m); --int mcast_bundle_age(const struct mcast_snooping *ms, -- const struct mcast_group_bundle *b); --struct mcast_snooping *mcast_snooping_create(void); --struct mcast_snooping *mcast_snooping_ref(const struct mcast_snooping *); --void mcast_snooping_unref(struct mcast_snooping *); --bool mcast_snooping_run(struct mcast_snooping *ms); --void mcast_snooping_wait(struct mcast_snooping *ms); -- --/* Configuration. */ --void mcast_snooping_set_idle_time(struct mcast_snooping *ms, -- unsigned int idle_time) -- OVS_REQ_WRLOCK(ms->rwlock); --void mcast_snooping_set_max_entries(struct mcast_snooping *ms, -- size_t max_entries) -- OVS_REQ_WRLOCK(ms->rwlock); --bool --mcast_snooping_set_flood_unreg(struct mcast_snooping *ms, bool enable) -- OVS_REQ_WRLOCK(ms->rwlock); --void mcast_snooping_set_port_flood(struct mcast_snooping *ms, void *port, -- bool flood) -- OVS_REQ_WRLOCK(ms->rwlock); --void mcast_snooping_set_port_flood_reports(struct mcast_snooping *ms, -- void *port, bool flood) -- OVS_REQ_WRLOCK(ms->rwlock); -- --/* Lookup. */ --struct mcast_group * --mcast_snooping_lookup(const struct mcast_snooping *ms, -- const struct in6_addr *dip, uint16_t vlan) -- OVS_REQ_RDLOCK(ms->rwlock); --struct mcast_group * --mcast_snooping_lookup4(const struct mcast_snooping *ms, ovs_be32 ip4, -- uint16_t vlan) -- OVS_REQ_RDLOCK(ms->rwlock); -- --/* Learning. */ --bool mcast_snooping_add_group(struct mcast_snooping *ms, -- const struct in6_addr *addr, -- uint16_t vlan, void *port) -- OVS_REQ_WRLOCK(ms->rwlock); --bool mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4, -- uint16_t vlan, void *port) -- OVS_REQ_WRLOCK(ms->rwlock); --int mcast_snooping_add_report(struct mcast_snooping *ms, -- const struct dp_packet *p, -- uint16_t vlan, void *port) -- OVS_REQ_WRLOCK(ms->rwlock); --int mcast_snooping_add_mld(struct mcast_snooping *ms, -- const struct dp_packet *p, -- uint16_t vlan, void *port) -- OVS_REQ_WRLOCK(ms->rwlock); --bool mcast_snooping_leave_group(struct mcast_snooping *ms, -- const struct in6_addr *addr, -- uint16_t vlan, void *port) -- OVS_REQ_WRLOCK(ms->rwlock); --bool mcast_snooping_leave_group4(struct mcast_snooping *ms, ovs_be32 ip4, -- uint16_t vlan, void *port) -- OVS_REQ_WRLOCK(ms->rwlock); --bool mcast_snooping_add_mrouter(struct mcast_snooping *ms, uint16_t vlan, -- void *port) -- OVS_REQ_WRLOCK(ms->rwlock); --bool mcast_snooping_is_query(ovs_be16 igmp_type); --bool mcast_snooping_is_membership(ovs_be16 igmp_type); -- --/* Flush. */ --void mcast_snooping_mdb_flush(struct mcast_snooping *ms); --void mcast_snooping_flush(struct mcast_snooping *ms); --void mcast_snooping_flush_bundle(struct mcast_snooping *ms, void *port); -- --#endif /* mcast-snooping.h */ -Index: openvswitch-2.17.2/include/internal/mcast-snooping.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/mcast-snooping.h -@@ -0,0 +1,219 @@ -+/* -+ * Copyright (c) 2014 Red Hat, Inc. -+ * -+ * Based on mac-learning implementation. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef MCAST_SNOOPING_H -+#define MCAST_SNOOPING_H 1 -+ -+#include -+#include "internal/dp-packet.h" -+#include "openvswitch/hmap.h" -+#include "openvswitch/list.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/timeval.h" -+ -+struct mcast_snooping; -+ -+/* Default maximum size of a mcast snooping table, in entries. */ -+#define MCAST_DEFAULT_MAX_ENTRIES 2048 -+ -+/* Time, in seconds, before expiring a mcast_group due to inactivity. */ -+#define MCAST_ENTRY_DEFAULT_IDLE_TIME 300 -+ -+/* Time, in seconds, before expiring a mrouter_port due to inactivity. */ -+#define MCAST_MROUTER_PORT_IDLE_TIME 180 -+ -+/* Multicast group entry. -+ * Guarded by owning 'mcast_snooping''s rwlock. */ -+struct mcast_group { -+ /* Node in parent struct mcast_snooping hmap. */ -+ struct hmap_node hmap_node; -+ -+ /* Multicast group IPv6/IPv4 address. */ -+ struct in6_addr addr; -+ -+ /* VLAN tag. */ -+ uint16_t vlan; -+ -+ /* Node in parent struct mcast_snooping group_lru. */ -+ struct ovs_list group_node OVS_GUARDED; -+ -+ /* Contains struct mcast_group_bundle (ports), least recently used -+ * at the front, most recently used at the back. */ -+ struct ovs_list bundle_lru OVS_GUARDED; -+}; -+ -+/* The bundle associated to the multicast group. -+ * Guarded by owning 'mcast_snooping''s rwlock. */ -+struct mcast_group_bundle { -+ /* Node in parent struct mcast_group bundle_lru list. */ -+ struct ovs_list bundle_node OVS_GUARDED; -+ -+ /* When this node expires. */ -+ time_t expires; -+ -+ /* Learned port. */ -+ void *port OVS_GUARDED; -+}; -+ -+/* The bundle connected to a multicast router. -+ * Guarded by owning 'mcast_snooping''s rwlock. */ -+struct mcast_mrouter_bundle { -+ /* Node in parent struct mcast_group mrouter_lru list. */ -+ struct ovs_list mrouter_node OVS_GUARDED; -+ -+ /* When this node expires. */ -+ time_t expires; -+ -+ /* VLAN tag. */ -+ uint16_t vlan; -+ -+ /* Learned port. */ -+ void *port OVS_GUARDED; -+}; -+ -+/* The bundle to send multicast traffic or Reports. -+ * Guarded by owning 'mcast_snooping''s rwlock */ -+struct mcast_port_bundle { -+ /* Node in parent struct mcast_snooping. */ -+ struct ovs_list node; -+ -+ /* VLAN tag. */ -+ uint16_t vlan; -+ -+ /* Learned port. */ -+ void *port; -+}; -+ -+/* Multicast snooping table. */ -+struct mcast_snooping { -+ /* Snooping/learning table. */ -+ struct hmap table; -+ -+ /* Contains struct mcast_group, least recently used at the front, -+ * most recently used at the back. */ -+ struct ovs_list group_lru OVS_GUARDED; -+ -+ /* Contains struct mcast_mrouter_bundle, least recently used at the -+ * front, most recently used at the back. */ -+ struct ovs_list mrouter_lru OVS_GUARDED; -+ -+ /* Contains struct mcast_port_bundle to be flooded with multicast -+ * packets in no special order. */ -+ struct ovs_list fport_list OVS_GUARDED; -+ -+ /* Contains struct mcast_port_bundle to forward Reports in -+ * no special order. */ -+ struct ovs_list rport_list OVS_GUARDED; -+ -+ /* Secret for randomizing hash table. */ -+ uint32_t secret; -+ -+ /* Maximum age before deleting an entry. */ -+ unsigned int idle_time; -+ -+ /* Maximum number of multicast groups learned. */ -+ size_t max_entries; -+ -+ /* True if flow revalidation is needed. */ -+ bool need_revalidate; -+ -+ /* True if unregistered multicast packets should be flooded to all -+ * ports, otherwise send them to ports connected to multicast routers. */ -+ bool flood_unreg; -+ -+ struct ovs_refcount ref_cnt; -+ struct ovs_rwlock rwlock; -+}; -+ -+/* Basics. */ -+bool mcast_snooping_enabled(const struct mcast_snooping *ms); -+bool mcast_snooping_flood_unreg(const struct mcast_snooping *ms); -+int mcast_mrouter_age(const struct mcast_snooping *ms, -+ const struct mcast_mrouter_bundle *m); -+int mcast_bundle_age(const struct mcast_snooping *ms, -+ const struct mcast_group_bundle *b); -+struct mcast_snooping *mcast_snooping_create(void); -+struct mcast_snooping *mcast_snooping_ref(const struct mcast_snooping *); -+void mcast_snooping_unref(struct mcast_snooping *); -+bool mcast_snooping_run(struct mcast_snooping *ms); -+void mcast_snooping_wait(struct mcast_snooping *ms); -+ -+/* Configuration. */ -+void mcast_snooping_set_idle_time(struct mcast_snooping *ms, -+ unsigned int idle_time) -+ OVS_REQ_WRLOCK(ms->rwlock); -+void mcast_snooping_set_max_entries(struct mcast_snooping *ms, -+ size_t max_entries) -+ OVS_REQ_WRLOCK(ms->rwlock); -+bool -+mcast_snooping_set_flood_unreg(struct mcast_snooping *ms, bool enable) -+ OVS_REQ_WRLOCK(ms->rwlock); -+void mcast_snooping_set_port_flood(struct mcast_snooping *ms, void *port, -+ bool flood) -+ OVS_REQ_WRLOCK(ms->rwlock); -+void mcast_snooping_set_port_flood_reports(struct mcast_snooping *ms, -+ void *port, bool flood) -+ OVS_REQ_WRLOCK(ms->rwlock); -+ -+/* Lookup. */ -+struct mcast_group * -+mcast_snooping_lookup(const struct mcast_snooping *ms, -+ const struct in6_addr *dip, uint16_t vlan) -+ OVS_REQ_RDLOCK(ms->rwlock); -+struct mcast_group * -+mcast_snooping_lookup4(const struct mcast_snooping *ms, ovs_be32 ip4, -+ uint16_t vlan) -+ OVS_REQ_RDLOCK(ms->rwlock); -+ -+/* Learning. */ -+bool mcast_snooping_add_group(struct mcast_snooping *ms, -+ const struct in6_addr *addr, -+ uint16_t vlan, void *port) -+ OVS_REQ_WRLOCK(ms->rwlock); -+bool mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4, -+ uint16_t vlan, void *port) -+ OVS_REQ_WRLOCK(ms->rwlock); -+int mcast_snooping_add_report(struct mcast_snooping *ms, -+ const struct dp_packet *p, -+ uint16_t vlan, void *port) -+ OVS_REQ_WRLOCK(ms->rwlock); -+int mcast_snooping_add_mld(struct mcast_snooping *ms, -+ const struct dp_packet *p, -+ uint16_t vlan, void *port) -+ OVS_REQ_WRLOCK(ms->rwlock); -+bool mcast_snooping_leave_group(struct mcast_snooping *ms, -+ const struct in6_addr *addr, -+ uint16_t vlan, void *port) -+ OVS_REQ_WRLOCK(ms->rwlock); -+bool mcast_snooping_leave_group4(struct mcast_snooping *ms, ovs_be32 ip4, -+ uint16_t vlan, void *port) -+ OVS_REQ_WRLOCK(ms->rwlock); -+bool mcast_snooping_add_mrouter(struct mcast_snooping *ms, uint16_t vlan, -+ void *port) -+ OVS_REQ_WRLOCK(ms->rwlock); -+bool mcast_snooping_is_query(ovs_be16 igmp_type); -+bool mcast_snooping_is_membership(ovs_be16 igmp_type); -+ -+/* Flush. */ -+void mcast_snooping_mdb_flush(struct mcast_snooping *ms); -+void mcast_snooping_flush(struct mcast_snooping *ms); -+void mcast_snooping_flush_bundle(struct mcast_snooping *ms, void *port); -+ -+#endif /* mcast-snooping.h */ -Index: openvswitch-2.17.2/lib/netdev.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev.h -+++ /dev/null -@@ -1,364 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef NETDEV_H --#define NETDEV_H 1 -- --#include "openvswitch/netdev.h" --#include "openvswitch/types.h" --#include "packets.h" --#include "flow.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --/* Generic interface to network devices ("netdev"s). -- * -- * Every port on a switch must have a corresponding netdev that must minimally -- * support a few operations, such as the ability to read the netdev's MTU. -- * The Porting section of the documentation has more information in the -- * "Writing a netdev Provider" section. -- * -- * Thread-safety -- * ============= -- * -- * Most of the netdev functions are fully thread-safe: they may be called from -- * any number of threads on the same or different netdev objects. The -- * exceptions are: -- * -- * netdev_rxq_recv() -- * netdev_rxq_wait() -- * netdev_rxq_drain() -- * -- * These functions are conditionally thread-safe: they may be called from -- * different threads only on different netdev_rxq objects. (The client may -- * create multiple netdev_rxq objects for a single netdev and access each -- * of those from a different thread.) -- * -- * NETDEV_QUEUE_FOR_EACH -- * netdev_queue_dump_next() -- * netdev_queue_dump_done() -- * -- * These functions are conditionally thread-safe: they may be called from -- * different threads only on different netdev_queue_dump objects. (The -- * client may create multiple netdev_queue_dump objects for a single -- * netdev and access each of those from a different thread.) -- */ -- --struct dp_packet_batch; --struct dp_packet; --struct netdev_class; --struct netdev_rxq; --struct netdev_saved_flags; --struct ofpbuf; --struct in_addr; --struct in6_addr; --struct smap; --struct sset; --struct ovs_action_push_tnl; -- --enum netdev_pt_mode { -- /* The netdev is packet type aware. It can potentially carry any kind of -- * packet. This "modern" mode is appropriate for both netdevs that handle -- * only a single kind of packet (such as a virtual or physical Ethernet -- * interface) and for those that can handle multiple (such as VXLAN-GPE or -- * Geneve). */ -- NETDEV_PT_AWARE, -- -- /* The netdev sends and receives only Ethernet frames. The netdev cannot -- * carry packets other than Ethernet frames. This is a legacy mode for -- * backward compability with controllers that are not prepared to handle -- * OpenFlow 1.5+ "packet_type". */ -- NETDEV_PT_LEGACY_L2, -- -- /* The netdev sends and receives only IPv4 and IPv6 packets. The netdev -- * cannot carry Ethernet frames or other kinds of packets. -- * -- * IPv4 and IPv6 packets carried over the netdev are treated as Ethernet: -- * when they are received, they are converted to Ethernet by adding a dummy -- * header with the proper Ethertype; on tranmission, the Ethernet header is -- * stripped. This is a legacy mode for backward compability with -- * controllers that are not prepared to handle OpenFlow 1.5+ -- * "packet_type". */ -- NETDEV_PT_LEGACY_L3, --}; -- --/* Configuration specific to tunnels. */ --struct netdev_tunnel_config { -- ovs_be64 in_key; -- bool in_key_present; -- bool in_key_flow; -- -- bool out_key_present; -- bool out_key_flow; -- ovs_be64 out_key; -- -- ovs_be16 payload_ethertype; -- ovs_be16 dst_port; -- -- bool ip_src_flow; -- bool ip_dst_flow; -- struct in6_addr ipv6_src; -- struct in6_addr ipv6_dst; -- -- uint32_t exts; -- uint32_t egress_pkt_mark; -- bool set_egress_pkt_mark; -- -- uint8_t ttl; -- bool ttl_inherit; -- -- uint8_t tos; -- bool tos_inherit; -- -- bool csum; -- bool dont_fragment; -- enum netdev_pt_mode pt_mode; -- -- bool set_seq; -- uint32_t seqno; -- uint32_t erspan_idx; -- uint8_t erspan_ver; -- uint8_t erspan_dir; -- uint8_t erspan_hwid; -- -- bool erspan_ver_flow; -- bool erspan_idx_flow; -- bool erspan_dir_flow; -- bool erspan_hwid_flow; --}; -- --void netdev_run(void); --void netdev_wait(void); -- --void netdev_enumerate_types(struct sset *types); --bool netdev_is_reserved_name(const char *name); -- --int netdev_n_txq(const struct netdev *netdev); --int netdev_n_rxq(const struct netdev *netdev); --bool netdev_is_pmd(const struct netdev *netdev); --bool netdev_has_tunnel_push_pop(const struct netdev *netdev); -- --/* Open and close. */ --int netdev_open(const char *name, const char *type, struct netdev **netdevp); -- --struct netdev *netdev_ref(const struct netdev *); --void netdev_remove(struct netdev *); --void netdev_close(struct netdev *); -- --void netdev_parse_name(const char *netdev_name, char **name, char **type); -- --/* Options. */ --int netdev_set_config(struct netdev *, const struct smap *args, char **errp); --int netdev_get_config(const struct netdev *, struct smap *); --const struct netdev_tunnel_config * -- netdev_get_tunnel_config(const struct netdev *); --int netdev_get_numa_id(const struct netdev *); -- --/* Basic properties. */ --const char *netdev_get_name(const struct netdev *); --const char *netdev_get_type(const struct netdev *); --const char *netdev_get_type_from_name(const char *); --int netdev_get_mtu(const struct netdev *, int *mtup); --int netdev_set_mtu(struct netdev *, int mtu); --void netdev_mtu_user_config(struct netdev *, bool); --bool netdev_mtu_is_user_config(struct netdev *); --int netdev_get_ifindex(const struct netdev *); --int netdev_set_tx_multiq(struct netdev *, unsigned int n_txq); --enum netdev_pt_mode netdev_get_pt_mode(const struct netdev *); --void netdev_set_dpif_type(struct netdev *, const char *); --const char *netdev_get_dpif_type(const struct netdev *); -- --/* Packet reception. */ --int netdev_rxq_open(struct netdev *, struct netdev_rxq **, int id); --void netdev_rxq_close(struct netdev_rxq *); --bool netdev_rxq_enabled(struct netdev_rxq *); -- --const char *netdev_rxq_get_name(const struct netdev_rxq *); --int netdev_rxq_get_queue_id(const struct netdev_rxq *); -- --int netdev_rxq_recv(struct netdev_rxq *rx, struct dp_packet_batch *, -- int *qfill); --void netdev_rxq_wait(struct netdev_rxq *); --int netdev_rxq_drain(struct netdev_rxq *); -- --/* Packet transmission. */ --int netdev_send(struct netdev *, int qid, struct dp_packet_batch *, -- bool concurrent_txq); --void netdev_send_wait(struct netdev *, int qid); -- --/* native tunnel APIs */ --/* Structure to pass parameters required to build a tunnel header. */ --struct netdev_tnl_build_header_params { -- const struct flow *flow; -- const struct in6_addr *s_ip; -- struct eth_addr dmac; -- struct eth_addr smac; -- bool is_ipv6; --}; -- --void --netdev_init_tnl_build_header_params(struct netdev_tnl_build_header_params *params, -- const struct flow *tnl_flow, -- const struct in6_addr *src, -- struct eth_addr dmac, -- struct eth_addr smac); -- --int netdev_build_header(const struct netdev *, struct ovs_action_push_tnl *data, -- const struct netdev_tnl_build_header_params *params); -- --int netdev_push_header(const struct netdev *netdev, -- struct dp_packet_batch *, -- const struct ovs_action_push_tnl *data); --void netdev_pop_header(struct netdev *netdev, struct dp_packet_batch *); -- --/* Hardware address. */ --int netdev_set_etheraddr(struct netdev *, const struct eth_addr mac); --int netdev_get_etheraddr(const struct netdev *, struct eth_addr *mac); -- --/* PHY interface. */ --bool netdev_get_carrier(const struct netdev *); --long long int netdev_get_carrier_resets(const struct netdev *); --int netdev_set_miimon_interval(struct netdev *, long long int interval); -- --/* Flags. */ --enum netdev_flags { -- NETDEV_UP = 0x0001, /* Device enabled? */ -- NETDEV_PROMISC = 0x0002, /* Promiscuous mode? */ -- NETDEV_LOOPBACK = 0x0004 /* This is a loopback device. */ --}; -- --int netdev_get_flags(const struct netdev *, enum netdev_flags *); --int netdev_set_flags(struct netdev *, enum netdev_flags, -- struct netdev_saved_flags **); --int netdev_turn_flags_on(struct netdev *, enum netdev_flags, -- struct netdev_saved_flags **); --int netdev_turn_flags_off(struct netdev *, enum netdev_flags, -- struct netdev_saved_flags **); -- --void netdev_restore_flags(struct netdev_saved_flags *); -- --/* TCP/IP stack interface. */ --int netdev_set_in4(struct netdev *, struct in_addr addr, struct in_addr mask); --int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4); --int netdev_get_ip_by_name(const char *device_name, struct in6_addr *); --int netdev_get_addr_list(const struct netdev *netdev, struct in6_addr **addr, -- struct in6_addr **mask, int *n_in6); -- --int netdev_add_router(struct netdev *, struct in_addr router); --int netdev_get_next_hop(const struct netdev *, const struct in_addr *host, -- struct in_addr *next_hop, char **); --int netdev_get_status(const struct netdev *, struct smap *); --int netdev_arp_lookup(const struct netdev *, ovs_be32 ip, -- struct eth_addr *mac); -- --struct netdev *netdev_find_dev_by_in4(const struct in_addr *); -- --/* Statistics. */ --int netdev_get_stats(const struct netdev *, struct netdev_stats *); --int netdev_get_custom_stats(const struct netdev *, -- struct netdev_custom_stats *); -- --/* Quality of service. */ --struct netdev_qos_capabilities { -- unsigned int n_queues; --}; -- --struct netdev_queue_stats { -- /* Values of unsupported statistics are set to all-1-bits (UINT64_MAX). */ -- uint64_t tx_bytes; -- uint64_t tx_packets; -- uint64_t tx_errors; -- -- /* Time at which the queue was created, in msecs, LLONG_MIN if unknown. */ -- long long int created; --}; -- --int netdev_set_policing(struct netdev *, uint32_t kbits_rate, -- uint32_t kbits_burst, uint32_t kpkts_rate, -- uint32_t kpkts_burst); -- --int netdev_get_qos_types(const struct netdev *, struct sset *types); --int netdev_get_qos_capabilities(const struct netdev *, -- const char *type, -- struct netdev_qos_capabilities *); --int netdev_get_n_queues(const struct netdev *, -- const char *type, unsigned int *n_queuesp); -- --int netdev_get_qos(const struct netdev *, -- const char **typep, struct smap *details); --int netdev_set_qos(struct netdev *, -- const char *type, const struct smap *details); -- --int netdev_get_queue(const struct netdev *, -- unsigned int queue_id, struct smap *details); --int netdev_set_queue(struct netdev *, -- unsigned int queue_id, const struct smap *details); --int netdev_delete_queue(struct netdev *, unsigned int queue_id); --int netdev_get_queue_stats(const struct netdev *, unsigned int queue_id, -- struct netdev_queue_stats *); --uint64_t netdev_get_change_seq(const struct netdev *); -- --int netdev_reconfigure(struct netdev *netdev); --void netdev_wait_reconf_required(struct netdev *netdev); --bool netdev_is_reconf_required(struct netdev *netdev); -- --struct netdev_queue_dump { -- struct netdev *netdev; -- int error; -- void *state; --}; --void netdev_queue_dump_start(struct netdev_queue_dump *, -- const struct netdev *); --bool netdev_queue_dump_next(struct netdev_queue_dump *, -- unsigned int *queue_id, struct smap *details); --int netdev_queue_dump_done(struct netdev_queue_dump *); -- --/* Iterates through each queue in NETDEV, using DUMP as state. Fills QUEUE_ID -- * and DETAILS with information about queues. The client must initialize and -- * destroy DETAILS. -- * -- * Arguments all have pointer type. -- * -- * If you break out of the loop, then you need to free the dump structure by -- * hand using netdev_queue_dump_done(). */ --#define NETDEV_QUEUE_FOR_EACH(QUEUE_ID, DETAILS, DUMP, NETDEV) \ -- for (netdev_queue_dump_start(DUMP, NETDEV); \ -- (netdev_queue_dump_next(DUMP, QUEUE_ID, DETAILS) \ -- ? true \ -- : (netdev_queue_dump_done(DUMP), false)); \ -- ) -- --typedef void netdev_dump_queue_stats_cb(unsigned int queue_id, -- struct netdev_queue_stats *, -- void *aux); --int netdev_dump_queue_stats(const struct netdev *, -- netdev_dump_queue_stats_cb *, void *aux); -- --extern struct seq *tnl_conf_seq; -- --#ifndef _WIN32 --void netdev_get_addrs_list_flush(void); --int netdev_get_addrs(const char dev[], struct in6_addr **paddr, -- struct in6_addr **pmask, int *n_in6); --#endif -- --#ifdef __cplusplus --} --#endif -- --#endif /* netdev.h */ -Index: openvswitch-2.17.2/include/internal/netdev.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/netdev.h -@@ -0,0 +1,364 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef NETDEV_H -+#define NETDEV_H 1 -+ -+#include "openvswitch/netdev.h" -+#include "openvswitch/types.h" -+#include "internal/packets.h" -+#include "internal/flow.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Generic interface to network devices ("netdev"s). -+ * -+ * Every port on a switch must have a corresponding netdev that must minimally -+ * support a few operations, such as the ability to read the netdev's MTU. -+ * The Porting section of the documentation has more information in the -+ * "Writing a netdev Provider" section. -+ * -+ * Thread-safety -+ * ============= -+ * -+ * Most of the netdev functions are fully thread-safe: they may be called from -+ * any number of threads on the same or different netdev objects. The -+ * exceptions are: -+ * -+ * netdev_rxq_recv() -+ * netdev_rxq_wait() -+ * netdev_rxq_drain() -+ * -+ * These functions are conditionally thread-safe: they may be called from -+ * different threads only on different netdev_rxq objects. (The client may -+ * create multiple netdev_rxq objects for a single netdev and access each -+ * of those from a different thread.) -+ * -+ * NETDEV_QUEUE_FOR_EACH -+ * netdev_queue_dump_next() -+ * netdev_queue_dump_done() -+ * -+ * These functions are conditionally thread-safe: they may be called from -+ * different threads only on different netdev_queue_dump objects. (The -+ * client may create multiple netdev_queue_dump objects for a single -+ * netdev and access each of those from a different thread.) -+ */ -+ -+struct dp_packet_batch; -+struct dp_packet; -+struct netdev_class; -+struct netdev_rxq; -+struct netdev_saved_flags; -+struct ofpbuf; -+struct in_addr; -+struct in6_addr; -+struct smap; -+struct sset; -+struct ovs_action_push_tnl; -+ -+enum netdev_pt_mode { -+ /* The netdev is packet type aware. It can potentially carry any kind of -+ * packet. This "modern" mode is appropriate for both netdevs that handle -+ * only a single kind of packet (such as a virtual or physical Ethernet -+ * interface) and for those that can handle multiple (such as VXLAN-GPE or -+ * Geneve). */ -+ NETDEV_PT_AWARE, -+ -+ /* The netdev sends and receives only Ethernet frames. The netdev cannot -+ * carry packets other than Ethernet frames. This is a legacy mode for -+ * backward compability with controllers that are not prepared to handle -+ * OpenFlow 1.5+ "packet_type". */ -+ NETDEV_PT_LEGACY_L2, -+ -+ /* The netdev sends and receives only IPv4 and IPv6 packets. The netdev -+ * cannot carry Ethernet frames or other kinds of packets. -+ * -+ * IPv4 and IPv6 packets carried over the netdev are treated as Ethernet: -+ * when they are received, they are converted to Ethernet by adding a dummy -+ * header with the proper Ethertype; on tranmission, the Ethernet header is -+ * stripped. This is a legacy mode for backward compability with -+ * controllers that are not prepared to handle OpenFlow 1.5+ -+ * "packet_type". */ -+ NETDEV_PT_LEGACY_L3, -+}; -+ -+/* Configuration specific to tunnels. */ -+struct netdev_tunnel_config { -+ ovs_be64 in_key; -+ bool in_key_present; -+ bool in_key_flow; -+ -+ bool out_key_present; -+ bool out_key_flow; -+ ovs_be64 out_key; -+ -+ ovs_be16 payload_ethertype; -+ ovs_be16 dst_port; -+ -+ bool ip_src_flow; -+ bool ip_dst_flow; -+ struct in6_addr ipv6_src; -+ struct in6_addr ipv6_dst; -+ -+ uint32_t exts; -+ uint32_t egress_pkt_mark; -+ bool set_egress_pkt_mark; -+ -+ uint8_t ttl; -+ bool ttl_inherit; -+ -+ uint8_t tos; -+ bool tos_inherit; -+ -+ bool csum; -+ bool dont_fragment; -+ enum netdev_pt_mode pt_mode; -+ -+ bool set_seq; -+ uint32_t seqno; -+ uint32_t erspan_idx; -+ uint8_t erspan_ver; -+ uint8_t erspan_dir; -+ uint8_t erspan_hwid; -+ -+ bool erspan_ver_flow; -+ bool erspan_idx_flow; -+ bool erspan_dir_flow; -+ bool erspan_hwid_flow; -+}; -+ -+void netdev_run(void); -+void netdev_wait(void); -+ -+void netdev_enumerate_types(struct sset *types); -+bool netdev_is_reserved_name(const char *name); -+ -+int netdev_n_txq(const struct netdev *netdev); -+int netdev_n_rxq(const struct netdev *netdev); -+bool netdev_is_pmd(const struct netdev *netdev); -+bool netdev_has_tunnel_push_pop(const struct netdev *netdev); -+ -+/* Open and close. */ -+int netdev_open(const char *name, const char *type, struct netdev **netdevp); -+ -+struct netdev *netdev_ref(const struct netdev *); -+void netdev_remove(struct netdev *); -+void netdev_close(struct netdev *); -+ -+void netdev_parse_name(const char *netdev_name, char **name, char **type); -+ -+/* Options. */ -+int netdev_set_config(struct netdev *, const struct smap *args, char **errp); -+int netdev_get_config(const struct netdev *, struct smap *); -+const struct netdev_tunnel_config * -+ netdev_get_tunnel_config(const struct netdev *); -+int netdev_get_numa_id(const struct netdev *); -+ -+/* Basic properties. */ -+const char *netdev_get_name(const struct netdev *); -+const char *netdev_get_type(const struct netdev *); -+const char *netdev_get_type_from_name(const char *); -+int netdev_get_mtu(const struct netdev *, int *mtup); -+int netdev_set_mtu(struct netdev *, int mtu); -+void netdev_mtu_user_config(struct netdev *, bool); -+bool netdev_mtu_is_user_config(struct netdev *); -+int netdev_get_ifindex(const struct netdev *); -+int netdev_set_tx_multiq(struct netdev *, unsigned int n_txq); -+enum netdev_pt_mode netdev_get_pt_mode(const struct netdev *); -+void netdev_set_dpif_type(struct netdev *, const char *); -+const char *netdev_get_dpif_type(const struct netdev *); -+ -+/* Packet reception. */ -+int netdev_rxq_open(struct netdev *, struct netdev_rxq **, int id); -+void netdev_rxq_close(struct netdev_rxq *); -+bool netdev_rxq_enabled(struct netdev_rxq *); -+ -+const char *netdev_rxq_get_name(const struct netdev_rxq *); -+int netdev_rxq_get_queue_id(const struct netdev_rxq *); -+ -+int netdev_rxq_recv(struct netdev_rxq *rx, struct dp_packet_batch *, -+ int *qfill); -+void netdev_rxq_wait(struct netdev_rxq *); -+int netdev_rxq_drain(struct netdev_rxq *); -+ -+/* Packet transmission. */ -+int netdev_send(struct netdev *, int qid, struct dp_packet_batch *, -+ bool concurrent_txq); -+void netdev_send_wait(struct netdev *, int qid); -+ -+/* native tunnel APIs */ -+/* Structure to pass parameters required to build a tunnel header. */ -+struct netdev_tnl_build_header_params { -+ const struct flow *flow; -+ const struct in6_addr *s_ip; -+ struct eth_addr dmac; -+ struct eth_addr smac; -+ bool is_ipv6; -+}; -+ -+void -+netdev_init_tnl_build_header_params(struct netdev_tnl_build_header_params *params, -+ const struct flow *tnl_flow, -+ const struct in6_addr *src, -+ struct eth_addr dmac, -+ struct eth_addr smac); -+ -+int netdev_build_header(const struct netdev *, struct ovs_action_push_tnl *data, -+ const struct netdev_tnl_build_header_params *params); -+ -+int netdev_push_header(const struct netdev *netdev, -+ struct dp_packet_batch *, -+ const struct ovs_action_push_tnl *data); -+void netdev_pop_header(struct netdev *netdev, struct dp_packet_batch *); -+ -+/* Hardware address. */ -+int netdev_set_etheraddr(struct netdev *, const struct eth_addr mac); -+int netdev_get_etheraddr(const struct netdev *, struct eth_addr *mac); -+ -+/* PHY interface. */ -+bool netdev_get_carrier(const struct netdev *); -+long long int netdev_get_carrier_resets(const struct netdev *); -+int netdev_set_miimon_interval(struct netdev *, long long int interval); -+ -+/* Flags. */ -+enum netdev_flags { -+ NETDEV_UP = 0x0001, /* Device enabled? */ -+ NETDEV_PROMISC = 0x0002, /* Promiscuous mode? */ -+ NETDEV_LOOPBACK = 0x0004 /* This is a loopback device. */ -+}; -+ -+int netdev_get_flags(const struct netdev *, enum netdev_flags *); -+int netdev_set_flags(struct netdev *, enum netdev_flags, -+ struct netdev_saved_flags **); -+int netdev_turn_flags_on(struct netdev *, enum netdev_flags, -+ struct netdev_saved_flags **); -+int netdev_turn_flags_off(struct netdev *, enum netdev_flags, -+ struct netdev_saved_flags **); -+ -+void netdev_restore_flags(struct netdev_saved_flags *); -+ -+/* TCP/IP stack interface. */ -+int netdev_set_in4(struct netdev *, struct in_addr addr, struct in_addr mask); -+int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4); -+int netdev_get_ip_by_name(const char *device_name, struct in6_addr *); -+int netdev_get_addr_list(const struct netdev *netdev, struct in6_addr **addr, -+ struct in6_addr **mask, int *n_in6); -+ -+int netdev_add_router(struct netdev *, struct in_addr router); -+int netdev_get_next_hop(const struct netdev *, const struct in_addr *host, -+ struct in_addr *next_hop, char **); -+int netdev_get_status(const struct netdev *, struct smap *); -+int netdev_arp_lookup(const struct netdev *, ovs_be32 ip, -+ struct eth_addr *mac); -+ -+struct netdev *netdev_find_dev_by_in4(const struct in_addr *); -+ -+/* Statistics. */ -+int netdev_get_stats(const struct netdev *, struct netdev_stats *); -+int netdev_get_custom_stats(const struct netdev *, -+ struct netdev_custom_stats *); -+ -+/* Quality of service. */ -+struct netdev_qos_capabilities { -+ unsigned int n_queues; -+}; -+ -+struct netdev_queue_stats { -+ /* Values of unsupported statistics are set to all-1-bits (UINT64_MAX). */ -+ uint64_t tx_bytes; -+ uint64_t tx_packets; -+ uint64_t tx_errors; -+ -+ /* Time at which the queue was created, in msecs, LLONG_MIN if unknown. */ -+ long long int created; -+}; -+ -+int netdev_set_policing(struct netdev *, uint32_t kbits_rate, -+ uint32_t kbits_burst, uint32_t kpkts_rate, -+ uint32_t kpkts_burst); -+ -+int netdev_get_qos_types(const struct netdev *, struct sset *types); -+int netdev_get_qos_capabilities(const struct netdev *, -+ const char *type, -+ struct netdev_qos_capabilities *); -+int netdev_get_n_queues(const struct netdev *, -+ const char *type, unsigned int *n_queuesp); -+ -+int netdev_get_qos(const struct netdev *, -+ const char **typep, struct smap *details); -+int netdev_set_qos(struct netdev *, -+ const char *type, const struct smap *details); -+ -+int netdev_get_queue(const struct netdev *, -+ unsigned int queue_id, struct smap *details); -+int netdev_set_queue(struct netdev *, -+ unsigned int queue_id, const struct smap *details); -+int netdev_delete_queue(struct netdev *, unsigned int queue_id); -+int netdev_get_queue_stats(const struct netdev *, unsigned int queue_id, -+ struct netdev_queue_stats *); -+uint64_t netdev_get_change_seq(const struct netdev *); -+ -+int netdev_reconfigure(struct netdev *netdev); -+void netdev_wait_reconf_required(struct netdev *netdev); -+bool netdev_is_reconf_required(struct netdev *netdev); -+ -+struct netdev_queue_dump { -+ struct netdev *netdev; -+ int error; -+ void *state; -+}; -+void netdev_queue_dump_start(struct netdev_queue_dump *, -+ const struct netdev *); -+bool netdev_queue_dump_next(struct netdev_queue_dump *, -+ unsigned int *queue_id, struct smap *details); -+int netdev_queue_dump_done(struct netdev_queue_dump *); -+ -+/* Iterates through each queue in NETDEV, using DUMP as state. Fills QUEUE_ID -+ * and DETAILS with information about queues. The client must initialize and -+ * destroy DETAILS. -+ * -+ * Arguments all have pointer type. -+ * -+ * If you break out of the loop, then you need to free the dump structure by -+ * hand using netdev_queue_dump_done(). */ -+#define NETDEV_QUEUE_FOR_EACH(QUEUE_ID, DETAILS, DUMP, NETDEV) \ -+ for (netdev_queue_dump_start(DUMP, NETDEV); \ -+ (netdev_queue_dump_next(DUMP, QUEUE_ID, DETAILS) \ -+ ? true \ -+ : (netdev_queue_dump_done(DUMP), false)); \ -+ ) -+ -+typedef void netdev_dump_queue_stats_cb(unsigned int queue_id, -+ struct netdev_queue_stats *, -+ void *aux); -+int netdev_dump_queue_stats(const struct netdev *, -+ netdev_dump_queue_stats_cb *, void *aux); -+ -+extern struct seq *tnl_conf_seq; -+ -+#ifndef _WIN32 -+void netdev_get_addrs_list_flush(void); -+int netdev_get_addrs(const char dev[], struct in6_addr **paddr, -+ struct in6_addr **pmask, int *n_in6); -+#endif -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* netdev.h */ -Index: openvswitch-2.17.2/lib/netlink-protocol.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink-protocol.h -+++ /dev/null -@@ -1,208 +0,0 @@ --/* -- * Copyright (c) 2008, 2010, 2011, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef NETLINK_PROTOCOL_H --#define NETLINK_PROTOCOL_H 1 -- --/* Netlink protocol definitions. -- * -- * Netlink is a message framing format described in RFC 3549 and used heavily -- * in Linux to access the network stack. Open vSwitch uses AF_NETLINK sockets -- * for this purpose on Linux. But on all platforms, Open vSwitch uses Netlink -- * message framing internally for certain purposes. -- * -- * This header provides access to the Netlink message framing definitions -- * regardless of platform. On Linux, it includes the proper headers directly; -- * on other platforms it directly defines the structures and macros itself. -- */ -- --#include --#include --#include "util.h" -- --#ifdef HAVE_NETLINK --#include --#include -- --#else --#define NETLINK_NETFILTER 12 --#define NETLINK_GENERIC 16 -- --/* nlmsg_flags bits. */ --#define NLM_F_REQUEST 0x001 --#define NLM_F_MULTI 0x002 --#define NLM_F_ACK 0x004 --#define NLM_F_ECHO 0x008 -- --/* GET request flag.*/ --#define NLM_F_ROOT 0x100 --#define NLM_F_MATCH 0x200 --#define NLM_F_ATOMIC 0x400 --#define NLM_F_DUMP (NLM_F_ROOT | NLM_F_MATCH) -- --/* NEW request flags. */ --#define NLM_F_REPLACE 0x100 --#define NLM_F_EXCL 0x200 --#define NLM_F_CREATE 0x400 -- --/* nlmsg_type values. */ --#define NLMSG_NOOP 1 --#define NLMSG_ERROR 2 --#define NLMSG_DONE 3 --#define NLMSG_OVERRUN 4 -- --#define NLMSG_MIN_TYPE 0x10 -- --#define MAX_LINKS 32 -- --struct nlmsghdr { -- uint32_t nlmsg_len; -- uint16_t nlmsg_type; -- uint16_t nlmsg_flags; -- uint32_t nlmsg_seq; -- uint32_t nlmsg_pid; --}; --BUILD_ASSERT_DECL(sizeof(struct nlmsghdr) == 16); -- --#define NLMSG_ALIGNTO 4 --#define NLMSG_ALIGN(SIZE) ROUND_UP(SIZE, NLMSG_ALIGNTO) --#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) -- --struct nlmsgerr --{ -- int error; -- struct nlmsghdr msg; --}; --BUILD_ASSERT_DECL(sizeof(struct nlmsgerr) == 20); -- --struct genlmsghdr { -- uint8_t cmd; -- uint8_t version; -- uint16_t reserved; --}; --BUILD_ASSERT_DECL(sizeof(struct genlmsghdr) == 4); -- --#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) -- --struct nlattr { -- uint16_t nla_len; -- uint16_t nla_type; --}; --BUILD_ASSERT_DECL(sizeof(struct nlattr) == 4); -- --#define NLA_ALIGNTO 4 --#define NLA_ALIGN(SIZE) ROUND_UP(SIZE, NLA_ALIGNTO) --#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) -- --#define GENL_MIN_ID NLMSG_MIN_TYPE --#define GENL_MAX_ID 1023 -- --#define GENL_ID_CTRL NLMSG_MIN_TYPE -- --enum { -- CTRL_CMD_UNSPEC, -- CTRL_CMD_NEWFAMILY, -- CTRL_CMD_DELFAMILY, -- CTRL_CMD_GETFAMILY, -- CTRL_CMD_NEWOPS, -- CTRL_CMD_DELOPS, -- CTRL_CMD_GETOPS, -- __CTRL_CMD_MAX, --}; -- --#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1) -- --enum { -- CTRL_ATTR_UNSPEC, -- CTRL_ATTR_FAMILY_ID, -- CTRL_ATTR_FAMILY_NAME, -- CTRL_ATTR_VERSION, -- CTRL_ATTR_HDRSIZE, -- CTRL_ATTR_MAXATTR, -- CTRL_ATTR_OPS, -- __CTRL_ATTR_MAX, --}; -- --#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) -- --enum { -- CTRL_ATTR_OP_UNSPEC, -- CTRL_ATTR_OP_ID, -- CTRL_ATTR_OP_FLAGS, -- __CTRL_ATTR_OP_MAX, --}; -- --#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1) --#endif /* !HAVE_NETLINK */ -- --/* These were introduced all together in 2.6.24. */ --#ifndef NLA_TYPE_MASK --#define NLA_F_NESTED (1 << 15) --#define NLA_F_NET_BYTEORDER (1 << 14) --#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) --#endif -- --/* These were introduced all together in 2.6.14. (We want our programs to -- * support the newer kernel features even if compiled with older headers.) */ --#ifndef NETLINK_ADD_MEMBERSHIP --#define NETLINK_ADD_MEMBERSHIP 1 --#define NETLINK_DROP_MEMBERSHIP 2 --#endif -- --/* This was introduced in v4.2. (We want our programs to support the newer -- * kernel features even if compiled with older headers.) */ --#ifndef NETLINK_LISTEN_ALL_NSID --#define NETLINK_LISTEN_ALL_NSID 8 --#endif -- --/* These were introduced all together in 2.6.23. (We want our programs to -- * support the newer kernel features even if compiled with older headers.) */ --#ifndef CTRL_ATTR_MCAST_GRP_MAX -- --#undef CTRL_ATTR_MAX --#define CTRL_ATTR_MAX 7 --#define CTRL_ATTR_MCAST_GROUPS 7 -- --enum { -- CTRL_ATTR_MCAST_GRP_UNSPEC, -- CTRL_ATTR_MCAST_GRP_NAME, -- CTRL_ATTR_MCAST_GRP_ID, -- __CTRL_ATTR_MCAST_GRP_MAX, --}; -- --#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1) --#endif /* CTRL_ATTR_MCAST_GRP_MAX */ -- --#ifndef NETLINK_EXT_ACK -- --#define NETLINK_CAP_ACK 10 --#define NETLINK_EXT_ACK 11 -- --/* ACK message flags. */ --#define NLM_F_CAPPED 0x100 --#define NLM_F_ACK_TLVS 0x200 -- --enum { -- NLMSGERR_ATTR_UNUSED, -- NLMSGERR_ATTR_MSG, -- NLMSGERR_ATTR_OFFS, -- __NLMSGERR_ATTR_MAX, -- NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1 --}; -- --#endif /* NLM_F_ACK_TLVS */ -- --#endif /* netlink-protocol.h */ -Index: openvswitch-2.17.2/include/internal/netlink-protocol.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/netlink-protocol.h -@@ -0,0 +1,208 @@ -+/* -+ * Copyright (c) 2008, 2010, 2011, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef NETLINK_PROTOCOL_H -+#define NETLINK_PROTOCOL_H 1 -+ -+/* Netlink protocol definitions. -+ * -+ * Netlink is a message framing format described in RFC 3549 and used heavily -+ * in Linux to access the network stack. Open vSwitch uses AF_NETLINK sockets -+ * for this purpose on Linux. But on all platforms, Open vSwitch uses Netlink -+ * message framing internally for certain purposes. -+ * -+ * This header provides access to the Netlink message framing definitions -+ * regardless of platform. On Linux, it includes the proper headers directly; -+ * on other platforms it directly defines the structures and macros itself. -+ */ -+ -+#include -+#include -+#include "internal/util.h" -+ -+#ifdef HAVE_NETLINK -+#include -+#include -+ -+#else -+#define NETLINK_NETFILTER 12 -+#define NETLINK_GENERIC 16 -+ -+/* nlmsg_flags bits. */ -+#define NLM_F_REQUEST 0x001 -+#define NLM_F_MULTI 0x002 -+#define NLM_F_ACK 0x004 -+#define NLM_F_ECHO 0x008 -+ -+/* GET request flag.*/ -+#define NLM_F_ROOT 0x100 -+#define NLM_F_MATCH 0x200 -+#define NLM_F_ATOMIC 0x400 -+#define NLM_F_DUMP (NLM_F_ROOT | NLM_F_MATCH) -+ -+/* NEW request flags. */ -+#define NLM_F_REPLACE 0x100 -+#define NLM_F_EXCL 0x200 -+#define NLM_F_CREATE 0x400 -+ -+/* nlmsg_type values. */ -+#define NLMSG_NOOP 1 -+#define NLMSG_ERROR 2 -+#define NLMSG_DONE 3 -+#define NLMSG_OVERRUN 4 -+ -+#define NLMSG_MIN_TYPE 0x10 -+ -+#define MAX_LINKS 32 -+ -+struct nlmsghdr { -+ uint32_t nlmsg_len; -+ uint16_t nlmsg_type; -+ uint16_t nlmsg_flags; -+ uint32_t nlmsg_seq; -+ uint32_t nlmsg_pid; -+}; -+BUILD_ASSERT_DECL(sizeof(struct nlmsghdr) == 16); -+ -+#define NLMSG_ALIGNTO 4 -+#define NLMSG_ALIGN(SIZE) ROUND_UP(SIZE, NLMSG_ALIGNTO) -+#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) -+ -+struct nlmsgerr -+{ -+ int error; -+ struct nlmsghdr msg; -+}; -+BUILD_ASSERT_DECL(sizeof(struct nlmsgerr) == 20); -+ -+struct genlmsghdr { -+ uint8_t cmd; -+ uint8_t version; -+ uint16_t reserved; -+}; -+BUILD_ASSERT_DECL(sizeof(struct genlmsghdr) == 4); -+ -+#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) -+ -+struct nlattr { -+ uint16_t nla_len; -+ uint16_t nla_type; -+}; -+BUILD_ASSERT_DECL(sizeof(struct nlattr) == 4); -+ -+#define NLA_ALIGNTO 4 -+#define NLA_ALIGN(SIZE) ROUND_UP(SIZE, NLA_ALIGNTO) -+#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) -+ -+#define GENL_MIN_ID NLMSG_MIN_TYPE -+#define GENL_MAX_ID 1023 -+ -+#define GENL_ID_CTRL NLMSG_MIN_TYPE -+ -+enum { -+ CTRL_CMD_UNSPEC, -+ CTRL_CMD_NEWFAMILY, -+ CTRL_CMD_DELFAMILY, -+ CTRL_CMD_GETFAMILY, -+ CTRL_CMD_NEWOPS, -+ CTRL_CMD_DELOPS, -+ CTRL_CMD_GETOPS, -+ __CTRL_CMD_MAX, -+}; -+ -+#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1) -+ -+enum { -+ CTRL_ATTR_UNSPEC, -+ CTRL_ATTR_FAMILY_ID, -+ CTRL_ATTR_FAMILY_NAME, -+ CTRL_ATTR_VERSION, -+ CTRL_ATTR_HDRSIZE, -+ CTRL_ATTR_MAXATTR, -+ CTRL_ATTR_OPS, -+ __CTRL_ATTR_MAX, -+}; -+ -+#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) -+ -+enum { -+ CTRL_ATTR_OP_UNSPEC, -+ CTRL_ATTR_OP_ID, -+ CTRL_ATTR_OP_FLAGS, -+ __CTRL_ATTR_OP_MAX, -+}; -+ -+#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1) -+#endif /* !HAVE_NETLINK */ -+ -+/* These were introduced all together in 2.6.24. */ -+#ifndef NLA_TYPE_MASK -+#define NLA_F_NESTED (1 << 15) -+#define NLA_F_NET_BYTEORDER (1 << 14) -+#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) -+#endif -+ -+/* These were introduced all together in 2.6.14. (We want our programs to -+ * support the newer kernel features even if compiled with older headers.) */ -+#ifndef NETLINK_ADD_MEMBERSHIP -+#define NETLINK_ADD_MEMBERSHIP 1 -+#define NETLINK_DROP_MEMBERSHIP 2 -+#endif -+ -+/* This was introduced in v4.2. (We want our programs to support the newer -+ * kernel features even if compiled with older headers.) */ -+#ifndef NETLINK_LISTEN_ALL_NSID -+#define NETLINK_LISTEN_ALL_NSID 8 -+#endif -+ -+/* These were introduced all together in 2.6.23. (We want our programs to -+ * support the newer kernel features even if compiled with older headers.) */ -+#ifndef CTRL_ATTR_MCAST_GRP_MAX -+ -+#undef CTRL_ATTR_MAX -+#define CTRL_ATTR_MAX 7 -+#define CTRL_ATTR_MCAST_GROUPS 7 -+ -+enum { -+ CTRL_ATTR_MCAST_GRP_UNSPEC, -+ CTRL_ATTR_MCAST_GRP_NAME, -+ CTRL_ATTR_MCAST_GRP_ID, -+ __CTRL_ATTR_MCAST_GRP_MAX, -+}; -+ -+#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1) -+#endif /* CTRL_ATTR_MCAST_GRP_MAX */ -+ -+#ifndef NETLINK_EXT_ACK -+ -+#define NETLINK_CAP_ACK 10 -+#define NETLINK_EXT_ACK 11 -+ -+/* ACK message flags. */ -+#define NLM_F_CAPPED 0x100 -+#define NLM_F_ACK_TLVS 0x200 -+ -+enum { -+ NLMSGERR_ATTR_UNUSED, -+ NLMSGERR_ATTR_MSG, -+ NLMSGERR_ATTR_OFFS, -+ __NLMSGERR_ATTR_MAX, -+ NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1 -+}; -+ -+#endif /* NLM_F_ACK_TLVS */ -+ -+#endif /* netlink-protocol.h */ -Index: openvswitch-2.17.2/lib/netlink.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink.h -+++ /dev/null -@@ -1,251 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2015 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef NETLINK_H --#define NETLINK_H 1 -- --/* Netlink message helpers. -- * -- * Netlink is a datagram-based network protocol primarily for communication -- * between user processes and the kernel, and mainly on Linux. Netlink is -- * specified in RFC 3549, "Linux Netlink as an IP Services Protocol". -- * -- * Netlink is not suitable for use in physical networks of heterogeneous -- * machines because host byte order is used throughout. -- * -- * This header file defines helper functions for working with Netlink messages. -- * For Netlink protocol definitions, see netlink-protocol.h. For -- * Linux-specific definitions for Netlink sockets, see netlink-socket.h. -- */ -- --#include --#include --#include --#include --#include --#include "netlink-protocol.h" --#include "openvswitch/types.h" -- --struct ofpbuf; --struct nlattr; -- --/* Accessing headers and data. */ --struct nlmsghdr *nl_msg_nlmsghdr(const struct ofpbuf *); --struct genlmsghdr *nl_msg_genlmsghdr(const struct ofpbuf *); --bool nl_msg_nlmsgerr(const struct ofpbuf *, int *error, const char **attr_msg); --void nl_msg_reserve(struct ofpbuf *, size_t); -- --/* Appending and prepending headers and raw data. */ --void nl_msg_put_nlmsghdr(struct ofpbuf *, size_t expected_payload, -- uint32_t type, uint32_t flags); --void nl_msg_put_genlmsghdr(struct ofpbuf *, size_t expected_payload, -- int family, uint32_t flags, -- uint8_t cmd, uint8_t version); --void nl_msg_put(struct ofpbuf *, const void *, size_t); --void *nl_msg_put_uninit(struct ofpbuf *, size_t); --void nl_msg_push(struct ofpbuf *, const void *, size_t); --void *nl_msg_push_uninit(struct ofpbuf *, size_t); -- --/* Appending attributes. */ --void *nl_msg_put_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); --void *nl_msg_put_unspec_zero(struct ofpbuf *, uint16_t type, size_t); --void nl_msg_put_unspec(struct ofpbuf *, uint16_t type, const void *, size_t); --void nl_msg_put_flag(struct ofpbuf *, uint16_t type); --void nl_msg_put_u8(struct ofpbuf *, uint16_t type, uint8_t value); --void nl_msg_put_u16(struct ofpbuf *, uint16_t type, uint16_t value); --void nl_msg_put_u32(struct ofpbuf *, uint16_t type, uint32_t value); --void nl_msg_put_u64(struct ofpbuf *, uint16_t type, uint64_t value); --void nl_msg_put_u128(struct ofpbuf *, uint16_t type, ovs_u128 value); --void nl_msg_put_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); --void nl_msg_put_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); --void nl_msg_put_be64(struct ofpbuf *, uint16_t type, ovs_be64 value); --void nl_msg_put_be128(struct ofpbuf *, uint16_t type, ovs_be128 value); --void nl_msg_put_in6_addr(struct ofpbuf *msg, uint16_t type, -- const struct in6_addr *value); --void nl_msg_put_odp_port(struct ofpbuf *, uint16_t type, odp_port_t value); --void nl_msg_put_string__(struct ofpbuf *, uint16_t type, const char *value, -- size_t len); --void nl_msg_put_string(struct ofpbuf *, uint16_t type, const char *value); -- --size_t nl_msg_start_nested(struct ofpbuf *, uint16_t type); --void nl_msg_end_nested(struct ofpbuf *, size_t offset); --void nl_msg_cancel_nested(struct ofpbuf *, size_t offset); --bool nl_msg_end_non_empty_nested(struct ofpbuf *, size_t offset); --void nl_msg_put_nested(struct ofpbuf *, uint16_t type, -- const void *data, size_t size); -- --/* Prepending attributes. */ --void *nl_msg_push_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); --void nl_msg_push_unspec(struct ofpbuf *, uint16_t type, const void *, size_t); --void nl_msg_push_flag(struct ofpbuf *, uint16_t type); --void nl_msg_push_u8(struct ofpbuf *, uint16_t type, uint8_t value); --void nl_msg_push_u16(struct ofpbuf *, uint16_t type, uint16_t value); --void nl_msg_push_u32(struct ofpbuf *, uint16_t type, uint32_t value); --void nl_msg_push_u64(struct ofpbuf *, uint16_t type, uint64_t value); --void nl_msg_push_u128(struct ofpbuf *, uint16_t type, ovs_u128 value); --void nl_msg_push_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); --void nl_msg_push_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); --void nl_msg_push_be64(struct ofpbuf *, uint16_t type, ovs_be64 value); --void nl_msg_push_be128(struct ofpbuf *, uint16_t type, ovs_be128 value); --void nl_msg_push_string(struct ofpbuf *, uint16_t type, const char *value); -- --/* Separating buffers into individual messages. */ --struct nlmsghdr *nl_msg_next(struct ofpbuf *buffer, struct ofpbuf *msg); -- --/* Sizes of various attribute types, in bytes, including the attribute header -- * and padding. -- * -- * A minimum-size attribute is 4 bytes long: 4 bytes of header, no bytes of -- * payload, no padding. -- * -- * A maximum-size attribute is 65536 bytes long: 4 bytes of header, 65531 bytes -- * of payload, 1 byte of padding. (Thus, NL_ATTR_SIZE() of a maximum length -- * attribute payload does not fit in 16 bits.) */ --#define NL_ATTR_SIZE(PAYLOAD_SIZE) (NLA_HDRLEN + NLA_ALIGN(PAYLOAD_SIZE)) --#define NL_A_U8_SIZE NL_ATTR_SIZE(sizeof(uint8_t)) --#define NL_A_U16_SIZE NL_ATTR_SIZE(sizeof(uint16_t)) --#define NL_A_U32_SIZE NL_ATTR_SIZE(sizeof(uint32_t)) --#define NL_A_U64_SIZE NL_ATTR_SIZE(sizeof(uint64_t)) --#define NL_A_U128_SIZE NL_ATTR_SIZE(sizeof(ovs_u128)) --#define NL_A_BE16_SIZE NL_ATTR_SIZE(sizeof(ovs_be16)) --#define NL_A_BE32_SIZE NL_ATTR_SIZE(sizeof(ovs_be32)) --#define NL_A_BE64_SIZE NL_ATTR_SIZE(sizeof(ovs_be64)) --#define NL_A_BE128_SIZE NL_ATTR_SIZE(sizeof(ovs_be128)) --#define NL_A_FLAG_SIZE NL_ATTR_SIZE(0) --#define NL_A_IPV6_SIZE NL_ATTR_SIZE(sizeof(struct in6_addr)) --#define NL_A_LL_ADDR_ETH_SIZE NL_ATTR_SIZE(sizeof(struct eth_addr)) --#define NL_A_LL_ADDR_IB_SIZE NL_ATTR_SIZE(sizeof(struct ib_addr)) -- --bool nl_attr_oversized(size_t payload_size); -- --/* Netlink attribute types. */ --enum nl_attr_type --{ -- NL_A_NO_ATTR = 0, -- NL_A_UNSPEC, -- NL_A_U8, -- NL_A_U16, -- NL_A_BE16 = NL_A_U16, -- NL_A_U32, -- NL_A_BE32 = NL_A_U32, -- NL_A_U64, -- NL_A_BE64 = NL_A_U64, -- NL_A_U128, -- NL_A_BE128 = NL_A_U128, -- NL_A_STRING, -- NL_A_FLAG, -- NL_A_IPV6, -- NL_A_NESTED, -- NL_A_LL_ADDR, -- N_NL_ATTR_TYPES --}; -- --/* Netlink attribute iteration. */ --static inline struct nlattr * --nl_attr_next(const struct nlattr *nla) --{ -- return ALIGNED_CAST(struct nlattr *, -- ((uint8_t *) nla + NLA_ALIGN(nla->nla_len))); --} -- --static inline bool --nl_attr_is_valid(const struct nlattr *nla, size_t maxlen) --{ -- return (maxlen >= sizeof *nla -- && nla->nla_len >= sizeof *nla -- && nla->nla_len <= maxlen); --} -- --static inline size_t --nl_attr_len_pad(const struct nlattr *nla, size_t maxlen) --{ -- size_t len = NLA_ALIGN(nla->nla_len); -- -- return len <= maxlen ? len : nla->nla_len; --} -- --/* This macro is careful to check for attributes with bad lengths. */ --#define NL_ATTR_FOR_EACH(ITER, LEFT, ATTRS, ATTRS_LEN) \ -- for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ -- nl_attr_is_valid(ITER, LEFT); \ -- (LEFT) -= nl_attr_len_pad(ITER, LEFT), (ITER) = nl_attr_next(ITER)) -- -- --/* This macro does not check for attributes with bad lengths. It should only -- * be used with messages from trusted sources or with messages that have -- * already been validated (e.g. with NL_ATTR_FOR_EACH). */ --#define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \ -- for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ -- (LEFT) > 0; \ -- (LEFT) -= nl_attr_len_pad(ITER, LEFT), (ITER) = nl_attr_next(ITER)) -- --/* These variants are convenient for iterating nested attributes. */ --#define NL_NESTED_FOR_EACH(ITER, LEFT, A) \ -- NL_ATTR_FOR_EACH(ITER, LEFT, nl_attr_get(A), nl_attr_get_size(A)) --#define NL_NESTED_FOR_EACH_UNSAFE(ITER, LEFT, A) \ -- NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, nl_attr_get(A), nl_attr_get_size(A)) -- --/* Netlink attribute parsing. */ --int nl_attr_type(const struct nlattr *); --const void *nl_attr_get(const struct nlattr *); --size_t nl_attr_get_size(const struct nlattr *); --const void *nl_attr_get_unspec(const struct nlattr *, size_t size); --bool nl_attr_get_flag(const struct nlattr *); --uint8_t nl_attr_get_u8(const struct nlattr *); --uint16_t nl_attr_get_u16(const struct nlattr *); --uint32_t nl_attr_get_u32(const struct nlattr *); --uint64_t nl_attr_get_u64(const struct nlattr *); --ovs_u128 nl_attr_get_u128(const struct nlattr *); --ovs_be16 nl_attr_get_be16(const struct nlattr *); --ovs_be32 nl_attr_get_be32(const struct nlattr *); --ovs_be64 nl_attr_get_be64(const struct nlattr *); --ovs_be128 nl_attr_get_be128(const struct nlattr *); --struct in6_addr nl_attr_get_in6_addr(const struct nlattr *nla); --odp_port_t nl_attr_get_odp_port(const struct nlattr *); --const char *nl_attr_get_string(const struct nlattr *); --void nl_attr_get_nested(const struct nlattr *, struct ofpbuf *); --struct eth_addr nl_attr_get_eth_addr(const struct nlattr *nla); --struct ib_addr nl_attr_get_ib_addr(const struct nlattr *nla); -- --/* Netlink attribute policy. -- * -- * Specifies how to parse a single attribute from a Netlink message payload. -- */ --struct nl_policy --{ -- enum nl_attr_type type; -- size_t min_len, max_len; -- bool optional; --}; -- --#define NL_POLICY_FOR(TYPE) \ -- .type = NL_A_UNSPEC, .min_len = sizeof(TYPE), .max_len = sizeof(TYPE) -- --bool nl_attr_validate(const struct nlattr *, const struct nl_policy *); -- --bool nl_policy_parse(const struct ofpbuf *, size_t offset, -- const struct nl_policy[], -- struct nlattr *[], size_t n_attrs); --bool nl_parse_nested(const struct nlattr *, const struct nl_policy[], -- struct nlattr *[], size_t n_attrs); -- --const struct nlattr *nl_attr_find(const struct ofpbuf *, size_t hdr_len, -- uint16_t type); --const struct nlattr *nl_attr_find_nested(const struct nlattr *, uint16_t type); --const struct nlattr *nl_attr_find__(const struct nlattr *attrs, size_t size, -- uint16_t type); -- --#endif /* netlink.h */ -Index: openvswitch-2.17.2/include/internal/netlink.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/netlink.h -@@ -0,0 +1,251 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2015 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef NETLINK_H -+#define NETLINK_H 1 -+ -+/* Netlink message helpers. -+ * -+ * Netlink is a datagram-based network protocol primarily for communication -+ * between user processes and the kernel, and mainly on Linux. Netlink is -+ * specified in RFC 3549, "Linux Netlink as an IP Services Protocol". -+ * -+ * Netlink is not suitable for use in physical networks of heterogeneous -+ * machines because host byte order is used throughout. -+ * -+ * This header file defines helper functions for working with Netlink messages. -+ * For Netlink protocol definitions, see netlink-protocol.h. For -+ * Linux-specific definitions for Netlink sockets, see netlink-socket.h. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "internal/netlink-protocol.h" -+#include "openvswitch/types.h" -+ -+struct ofpbuf; -+struct nlattr; -+ -+/* Accessing headers and data. */ -+struct nlmsghdr *nl_msg_nlmsghdr(const struct ofpbuf *); -+struct genlmsghdr *nl_msg_genlmsghdr(const struct ofpbuf *); -+bool nl_msg_nlmsgerr(const struct ofpbuf *, int *error, const char **attr_msg); -+void nl_msg_reserve(struct ofpbuf *, size_t); -+ -+/* Appending and prepending headers and raw data. */ -+void nl_msg_put_nlmsghdr(struct ofpbuf *, size_t expected_payload, -+ uint32_t type, uint32_t flags); -+void nl_msg_put_genlmsghdr(struct ofpbuf *, size_t expected_payload, -+ int family, uint32_t flags, -+ uint8_t cmd, uint8_t version); -+void nl_msg_put(struct ofpbuf *, const void *, size_t); -+void *nl_msg_put_uninit(struct ofpbuf *, size_t); -+void nl_msg_push(struct ofpbuf *, const void *, size_t); -+void *nl_msg_push_uninit(struct ofpbuf *, size_t); -+ -+/* Appending attributes. */ -+void *nl_msg_put_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); -+void *nl_msg_put_unspec_zero(struct ofpbuf *, uint16_t type, size_t); -+void nl_msg_put_unspec(struct ofpbuf *, uint16_t type, const void *, size_t); -+void nl_msg_put_flag(struct ofpbuf *, uint16_t type); -+void nl_msg_put_u8(struct ofpbuf *, uint16_t type, uint8_t value); -+void nl_msg_put_u16(struct ofpbuf *, uint16_t type, uint16_t value); -+void nl_msg_put_u32(struct ofpbuf *, uint16_t type, uint32_t value); -+void nl_msg_put_u64(struct ofpbuf *, uint16_t type, uint64_t value); -+void nl_msg_put_u128(struct ofpbuf *, uint16_t type, ovs_u128 value); -+void nl_msg_put_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); -+void nl_msg_put_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); -+void nl_msg_put_be64(struct ofpbuf *, uint16_t type, ovs_be64 value); -+void nl_msg_put_be128(struct ofpbuf *, uint16_t type, ovs_be128 value); -+void nl_msg_put_in6_addr(struct ofpbuf *msg, uint16_t type, -+ const struct in6_addr *value); -+void nl_msg_put_odp_port(struct ofpbuf *, uint16_t type, odp_port_t value); -+void nl_msg_put_string__(struct ofpbuf *, uint16_t type, const char *value, -+ size_t len); -+void nl_msg_put_string(struct ofpbuf *, uint16_t type, const char *value); -+ -+size_t nl_msg_start_nested(struct ofpbuf *, uint16_t type); -+void nl_msg_end_nested(struct ofpbuf *, size_t offset); -+void nl_msg_cancel_nested(struct ofpbuf *, size_t offset); -+bool nl_msg_end_non_empty_nested(struct ofpbuf *, size_t offset); -+void nl_msg_put_nested(struct ofpbuf *, uint16_t type, -+ const void *data, size_t size); -+ -+/* Prepending attributes. */ -+void *nl_msg_push_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); -+void nl_msg_push_unspec(struct ofpbuf *, uint16_t type, const void *, size_t); -+void nl_msg_push_flag(struct ofpbuf *, uint16_t type); -+void nl_msg_push_u8(struct ofpbuf *, uint16_t type, uint8_t value); -+void nl_msg_push_u16(struct ofpbuf *, uint16_t type, uint16_t value); -+void nl_msg_push_u32(struct ofpbuf *, uint16_t type, uint32_t value); -+void nl_msg_push_u64(struct ofpbuf *, uint16_t type, uint64_t value); -+void nl_msg_push_u128(struct ofpbuf *, uint16_t type, ovs_u128 value); -+void nl_msg_push_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); -+void nl_msg_push_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); -+void nl_msg_push_be64(struct ofpbuf *, uint16_t type, ovs_be64 value); -+void nl_msg_push_be128(struct ofpbuf *, uint16_t type, ovs_be128 value); -+void nl_msg_push_string(struct ofpbuf *, uint16_t type, const char *value); -+ -+/* Separating buffers into individual messages. */ -+struct nlmsghdr *nl_msg_next(struct ofpbuf *buffer, struct ofpbuf *msg); -+ -+/* Sizes of various attribute types, in bytes, including the attribute header -+ * and padding. -+ * -+ * A minimum-size attribute is 4 bytes long: 4 bytes of header, no bytes of -+ * payload, no padding. -+ * -+ * A maximum-size attribute is 65536 bytes long: 4 bytes of header, 65531 bytes -+ * of payload, 1 byte of padding. (Thus, NL_ATTR_SIZE() of a maximum length -+ * attribute payload does not fit in 16 bits.) */ -+#define NL_ATTR_SIZE(PAYLOAD_SIZE) (NLA_HDRLEN + NLA_ALIGN(PAYLOAD_SIZE)) -+#define NL_A_U8_SIZE NL_ATTR_SIZE(sizeof(uint8_t)) -+#define NL_A_U16_SIZE NL_ATTR_SIZE(sizeof(uint16_t)) -+#define NL_A_U32_SIZE NL_ATTR_SIZE(sizeof(uint32_t)) -+#define NL_A_U64_SIZE NL_ATTR_SIZE(sizeof(uint64_t)) -+#define NL_A_U128_SIZE NL_ATTR_SIZE(sizeof(ovs_u128)) -+#define NL_A_BE16_SIZE NL_ATTR_SIZE(sizeof(ovs_be16)) -+#define NL_A_BE32_SIZE NL_ATTR_SIZE(sizeof(ovs_be32)) -+#define NL_A_BE64_SIZE NL_ATTR_SIZE(sizeof(ovs_be64)) -+#define NL_A_BE128_SIZE NL_ATTR_SIZE(sizeof(ovs_be128)) -+#define NL_A_FLAG_SIZE NL_ATTR_SIZE(0) -+#define NL_A_IPV6_SIZE NL_ATTR_SIZE(sizeof(struct in6_addr)) -+#define NL_A_LL_ADDR_ETH_SIZE NL_ATTR_SIZE(sizeof(struct eth_addr)) -+#define NL_A_LL_ADDR_IB_SIZE NL_ATTR_SIZE(sizeof(struct ib_addr)) -+ -+bool nl_attr_oversized(size_t payload_size); -+ -+/* Netlink attribute types. */ -+enum nl_attr_type -+{ -+ NL_A_NO_ATTR = 0, -+ NL_A_UNSPEC, -+ NL_A_U8, -+ NL_A_U16, -+ NL_A_BE16 = NL_A_U16, -+ NL_A_U32, -+ NL_A_BE32 = NL_A_U32, -+ NL_A_U64, -+ NL_A_BE64 = NL_A_U64, -+ NL_A_U128, -+ NL_A_BE128 = NL_A_U128, -+ NL_A_STRING, -+ NL_A_FLAG, -+ NL_A_IPV6, -+ NL_A_NESTED, -+ NL_A_LL_ADDR, -+ N_NL_ATTR_TYPES -+}; -+ -+/* Netlink attribute iteration. */ -+static inline struct nlattr * -+nl_attr_next(const struct nlattr *nla) -+{ -+ return ALIGNED_CAST(struct nlattr *, -+ ((uint8_t *) nla + NLA_ALIGN(nla->nla_len))); -+} -+ -+static inline bool -+nl_attr_is_valid(const struct nlattr *nla, size_t maxlen) -+{ -+ return (maxlen >= sizeof *nla -+ && nla->nla_len >= sizeof *nla -+ && nla->nla_len <= maxlen); -+} -+ -+static inline size_t -+nl_attr_len_pad(const struct nlattr *nla, size_t maxlen) -+{ -+ size_t len = NLA_ALIGN(nla->nla_len); -+ -+ return len <= maxlen ? len : nla->nla_len; -+} -+ -+/* This macro is careful to check for attributes with bad lengths. */ -+#define NL_ATTR_FOR_EACH(ITER, LEFT, ATTRS, ATTRS_LEN) \ -+ for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ -+ nl_attr_is_valid(ITER, LEFT); \ -+ (LEFT) -= nl_attr_len_pad(ITER, LEFT), (ITER) = nl_attr_next(ITER)) -+ -+ -+/* This macro does not check for attributes with bad lengths. It should only -+ * be used with messages from trusted sources or with messages that have -+ * already been validated (e.g. with NL_ATTR_FOR_EACH). */ -+#define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \ -+ for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ -+ (LEFT) > 0; \ -+ (LEFT) -= nl_attr_len_pad(ITER, LEFT), (ITER) = nl_attr_next(ITER)) -+ -+/* These variants are convenient for iterating nested attributes. */ -+#define NL_NESTED_FOR_EACH(ITER, LEFT, A) \ -+ NL_ATTR_FOR_EACH(ITER, LEFT, nl_attr_get(A), nl_attr_get_size(A)) -+#define NL_NESTED_FOR_EACH_UNSAFE(ITER, LEFT, A) \ -+ NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, nl_attr_get(A), nl_attr_get_size(A)) -+ -+/* Netlink attribute parsing. */ -+int nl_attr_type(const struct nlattr *); -+const void *nl_attr_get(const struct nlattr *); -+size_t nl_attr_get_size(const struct nlattr *); -+const void *nl_attr_get_unspec(const struct nlattr *, size_t size); -+bool nl_attr_get_flag(const struct nlattr *); -+uint8_t nl_attr_get_u8(const struct nlattr *); -+uint16_t nl_attr_get_u16(const struct nlattr *); -+uint32_t nl_attr_get_u32(const struct nlattr *); -+uint64_t nl_attr_get_u64(const struct nlattr *); -+ovs_u128 nl_attr_get_u128(const struct nlattr *); -+ovs_be16 nl_attr_get_be16(const struct nlattr *); -+ovs_be32 nl_attr_get_be32(const struct nlattr *); -+ovs_be64 nl_attr_get_be64(const struct nlattr *); -+ovs_be128 nl_attr_get_be128(const struct nlattr *); -+struct in6_addr nl_attr_get_in6_addr(const struct nlattr *nla); -+odp_port_t nl_attr_get_odp_port(const struct nlattr *); -+const char *nl_attr_get_string(const struct nlattr *); -+void nl_attr_get_nested(const struct nlattr *, struct ofpbuf *); -+struct eth_addr nl_attr_get_eth_addr(const struct nlattr *nla); -+struct ib_addr nl_attr_get_ib_addr(const struct nlattr *nla); -+ -+/* Netlink attribute policy. -+ * -+ * Specifies how to parse a single attribute from a Netlink message payload. -+ */ -+struct nl_policy -+{ -+ enum nl_attr_type type; -+ size_t min_len, max_len; -+ bool optional; -+}; -+ -+#define NL_POLICY_FOR(TYPE) \ -+ .type = NL_A_UNSPEC, .min_len = sizeof(TYPE), .max_len = sizeof(TYPE) -+ -+bool nl_attr_validate(const struct nlattr *, const struct nl_policy *); -+ -+bool nl_policy_parse(const struct ofpbuf *, size_t offset, -+ const struct nl_policy[], -+ struct nlattr *[], size_t n_attrs); -+bool nl_parse_nested(const struct nlattr *, const struct nl_policy[], -+ struct nlattr *[], size_t n_attrs); -+ -+const struct nlattr *nl_attr_find(const struct ofpbuf *, size_t hdr_len, -+ uint16_t type); -+const struct nlattr *nl_attr_find_nested(const struct nlattr *, uint16_t type); -+const struct nlattr *nl_attr_find__(const struct nlattr *attrs, size_t size, -+ uint16_t type); -+ -+#endif /* netlink.h */ -Index: openvswitch-2.17.2/lib/nx-match.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/nx-match.h -+++ /dev/null -@@ -1,181 +0,0 @@ --/* -- * Copyright (c) 2010-2017, 2020 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef NX_MATCH_H --#define NX_MATCH_H 1 -- --#include --#include --#include --#include "openvswitch/compiler.h" --#include "flow.h" --#include "openvswitch/meta-flow.h" --#include "openvswitch/ofp-errors.h" --#include "openvswitch/types.h" -- --struct ds; --struct match; --struct ofpact_reg_move; --struct ofpact_reg_load; --struct ofpact_stack; --struct ofpbuf; --struct nx_action_reg_load; --struct nx_action_reg_move; --struct vl_mff_map; -- -- --/* Nicira Extended Match (NXM) flexible flow match helper functions. -- * -- * See include/openflow/nicira-ext.h for NXM specification. -- */ -- --char * mf_parse_field(const struct mf_field **field, const char *s) -- OVS_WARN_UNUSED_RESULT; --void mf_format_subfield(const struct mf_subfield *, struct ds *); --char *mf_parse_subfield__(struct mf_subfield *sf, const char **s) -- OVS_WARN_UNUSED_RESULT; --char *mf_parse_subfield(struct mf_subfield *, const char *s) -- OVS_WARN_UNUSED_RESULT; -- --/* Decoding matches. */ --enum ofperr nx_pull_match(struct ofpbuf *, unsigned int match_len, -- struct match *, ovs_be64 *cookie, -- ovs_be64 *cookie_mask, bool pipeline_fields_only, -- const struct tun_table *, const struct vl_mff_map *); --enum ofperr nx_pull_match_loose(struct ofpbuf *, unsigned int match_len, -- struct match *, ovs_be64 *cookie, -- ovs_be64 *cookie_mask, -- bool pipeline_fields_only, -- const struct tun_table *); --enum ofperr oxm_pull_match(struct ofpbuf *, bool pipeline_fields_only, -- const struct tun_table *, const struct vl_mff_map *, -- struct match *); --enum ofperr oxm_pull_match_loose(struct ofpbuf *, bool pipeline_fields_only, -- const struct tun_table *, struct match *); --enum ofperr oxm_decode_match(const void *, size_t, bool, -- const struct tun_table *, -- const struct vl_mff_map *, struct match *); --enum ofperr oxm_pull_field_array(const void *, size_t fields_len, -- struct field_array *); -- --/* Encoding matches. */ --int nx_put_match(struct ofpbuf *, const struct match *, -- ovs_be64 cookie, ovs_be64 cookie_mask); --int oxm_put_match(struct ofpbuf *, const struct match *, enum ofp_version); --void oxm_put_raw(struct ofpbuf *, const struct match *, enum ofp_version); --void oxm_format_field_array(struct ds *, const struct field_array *); --int oxm_put_field_array(struct ofpbuf *, const struct field_array *, -- enum ofp_version version); -- --/* Decoding and encoding OXM/NXM headers (just a field ID) or entries (a field -- * ID followed by a value and possibly a mask). */ --enum ofperr nx_pull_entry(struct ofpbuf *, const struct vl_mff_map *, -- const struct mf_field **, union mf_value *value, -- union mf_value *mask, bool is_action); --enum ofperr nx_pull_header(struct ofpbuf *, const struct vl_mff_map *, -- const struct mf_field **, bool *masked); --void nxm_put_entry_raw(struct ofpbuf *, enum mf_field_id field, -- enum ofp_version version, const void *value, -- const void *mask, size_t n_bytes); --void nx_put_entry(struct ofpbuf *, const struct mf_field *, enum ofp_version, -- const union mf_value *value, const union mf_value *mask); --void nx_put_header(struct ofpbuf *, enum mf_field_id, enum ofp_version, -- bool masked); --void nx_put_mff_header(struct ofpbuf *, const struct mf_field *, -- enum ofp_version, bool); -- --/* NXM and OXM protocol headers values. -- * -- * These are often alternatives to nx_pull_entry/header() and -- * nx_put_entry/header() for decoding and encoding OXM/NXM. In those cases, -- * the nx_*() functions should be preferred because they can support the 64-bit -- * "experimenter" OXM format (even though it is not yet implemented). */ --uint32_t mf_nxm_header(enum mf_field_id); --uint32_t nxm_header_from_mff(const struct mf_field *); --const struct mf_field *mf_from_nxm_header(uint32_t nxm_header, -- const struct vl_mff_map *); -- --char *nx_match_to_string(const uint8_t *, unsigned int match_len); --char *oxm_match_to_string(const struct ofpbuf *, unsigned int match_len); --int nx_match_from_string(const char *, struct ofpbuf *); --int oxm_match_from_string(const char *, struct ofpbuf *); -- --void nx_format_field_name(enum mf_field_id, enum ofp_version, struct ds *); -- --char *nxm_parse_reg_move(struct ofpact_reg_move *, const char *) -- OVS_WARN_UNUSED_RESULT; -- --void nxm_format_reg_move(const struct ofpact_reg_move *, struct ds *); -- --enum ofperr nxm_reg_move_check(const struct ofpact_reg_move *, -- const struct match *); -- --void nxm_reg_load(const struct mf_subfield *, uint64_t src_data, -- struct flow *, struct flow_wildcards *); -- --char *nxm_parse_stack_action(struct ofpact_stack *, const char *) -- OVS_WARN_UNUSED_RESULT; -- --void nxm_format_stack_push(const struct ofpact_stack *, struct ds *); --void nxm_format_stack_pop(const struct ofpact_stack *, struct ds *); -- --enum ofperr nxm_stack_push_check(const struct ofpact_stack *, -- const struct match *); --enum ofperr nxm_stack_pop_check(const struct ofpact_stack *, -- const struct match *); --void nx_stack_push(struct ofpbuf *stack, const void *v, uint8_t bytes); --void nx_stack_push_bottom(struct ofpbuf *stack, const void *v, uint8_t bytes); --void *nx_stack_pop(struct ofpbuf *stack, uint8_t *bytes); -- --void nxm_execute_stack_push(const struct ofpact_stack *, -- const struct flow *, struct flow_wildcards *, -- struct ofpbuf *); --bool nxm_execute_stack_pop(const struct ofpact_stack *, -- struct flow *, struct flow_wildcards *, -- struct ofpbuf *); -- --ovs_be64 oxm_bitmap_from_mf_bitmap(const struct mf_bitmap *, enum ofp_version); --struct mf_bitmap oxm_bitmap_to_mf_bitmap(ovs_be64 oxm_bitmap, -- enum ofp_version); --struct mf_bitmap oxm_writable_fields(void); --struct mf_bitmap oxm_matchable_fields(void); --struct mf_bitmap oxm_maskable_fields(void); -- --/* Dealing with the 'ofs_nbits' members in several Nicira extensions. */ -- --static inline ovs_be16 --nxm_encode_ofs_nbits(int ofs, int n_bits) --{ -- return htons((ofs << 6) | (n_bits - 1)); --} -- --static inline int --nxm_decode_ofs(ovs_be16 ofs_nbits) --{ -- return ntohs(ofs_nbits) >> 6; --} -- --static inline int --nxm_decode_n_bits(ovs_be16 ofs_nbits) --{ -- return (ntohs(ofs_nbits) & 0x3f) + 1; --} -- --/* This is my guess at the length of a "typical" nx_match, for use in -- * predicting space requirements. */ --#define NXM_TYPICAL_LEN 64 -- --#endif /* nx-match.h */ -Index: openvswitch-2.17.2/include/internal/nx-match.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/nx-match.h -@@ -0,0 +1,181 @@ -+/* -+ * Copyright (c) 2010-2017, 2020 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef NX_MATCH_H -+#define NX_MATCH_H 1 -+ -+#include -+#include -+#include -+#include "openvswitch/compiler.h" -+#include "internal/flow.h" -+#include "openvswitch/meta-flow.h" -+#include "openvswitch/ofp-errors.h" -+#include "openvswitch/types.h" -+ -+struct ds; -+struct match; -+struct ofpact_reg_move; -+struct ofpact_reg_load; -+struct ofpact_stack; -+struct ofpbuf; -+struct nx_action_reg_load; -+struct nx_action_reg_move; -+struct vl_mff_map; -+ -+ -+/* Nicira Extended Match (NXM) flexible flow match helper functions. -+ * -+ * See include/openflow/nicira-ext.h for NXM specification. -+ */ -+ -+char * mf_parse_field(const struct mf_field **field, const char *s) -+ OVS_WARN_UNUSED_RESULT; -+void mf_format_subfield(const struct mf_subfield *, struct ds *); -+char *mf_parse_subfield__(struct mf_subfield *sf, const char **s) -+ OVS_WARN_UNUSED_RESULT; -+char *mf_parse_subfield(struct mf_subfield *, const char *s) -+ OVS_WARN_UNUSED_RESULT; -+ -+/* Decoding matches. */ -+enum ofperr nx_pull_match(struct ofpbuf *, unsigned int match_len, -+ struct match *, ovs_be64 *cookie, -+ ovs_be64 *cookie_mask, bool pipeline_fields_only, -+ const struct tun_table *, const struct vl_mff_map *); -+enum ofperr nx_pull_match_loose(struct ofpbuf *, unsigned int match_len, -+ struct match *, ovs_be64 *cookie, -+ ovs_be64 *cookie_mask, -+ bool pipeline_fields_only, -+ const struct tun_table *); -+enum ofperr oxm_pull_match(struct ofpbuf *, bool pipeline_fields_only, -+ const struct tun_table *, const struct vl_mff_map *, -+ struct match *); -+enum ofperr oxm_pull_match_loose(struct ofpbuf *, bool pipeline_fields_only, -+ const struct tun_table *, struct match *); -+enum ofperr oxm_decode_match(const void *, size_t, bool, -+ const struct tun_table *, -+ const struct vl_mff_map *, struct match *); -+enum ofperr oxm_pull_field_array(const void *, size_t fields_len, -+ struct field_array *); -+ -+/* Encoding matches. */ -+int nx_put_match(struct ofpbuf *, const struct match *, -+ ovs_be64 cookie, ovs_be64 cookie_mask); -+int oxm_put_match(struct ofpbuf *, const struct match *, enum ofp_version); -+void oxm_put_raw(struct ofpbuf *, const struct match *, enum ofp_version); -+void oxm_format_field_array(struct ds *, const struct field_array *); -+int oxm_put_field_array(struct ofpbuf *, const struct field_array *, -+ enum ofp_version version); -+ -+/* Decoding and encoding OXM/NXM headers (just a field ID) or entries (a field -+ * ID followed by a value and possibly a mask). */ -+enum ofperr nx_pull_entry(struct ofpbuf *, const struct vl_mff_map *, -+ const struct mf_field **, union mf_value *value, -+ union mf_value *mask, bool is_action); -+enum ofperr nx_pull_header(struct ofpbuf *, const struct vl_mff_map *, -+ const struct mf_field **, bool *masked); -+void nxm_put_entry_raw(struct ofpbuf *, enum mf_field_id field, -+ enum ofp_version version, const void *value, -+ const void *mask, size_t n_bytes); -+void nx_put_entry(struct ofpbuf *, const struct mf_field *, enum ofp_version, -+ const union mf_value *value, const union mf_value *mask); -+void nx_put_header(struct ofpbuf *, enum mf_field_id, enum ofp_version, -+ bool masked); -+void nx_put_mff_header(struct ofpbuf *, const struct mf_field *, -+ enum ofp_version, bool); -+ -+/* NXM and OXM protocol headers values. -+ * -+ * These are often alternatives to nx_pull_entry/header() and -+ * nx_put_entry/header() for decoding and encoding OXM/NXM. In those cases, -+ * the nx_*() functions should be preferred because they can support the 64-bit -+ * "experimenter" OXM format (even though it is not yet implemented). */ -+uint32_t mf_nxm_header(enum mf_field_id); -+uint32_t nxm_header_from_mff(const struct mf_field *); -+const struct mf_field *mf_from_nxm_header(uint32_t nxm_header, -+ const struct vl_mff_map *); -+ -+char *nx_match_to_string(const uint8_t *, unsigned int match_len); -+char *oxm_match_to_string(const struct ofpbuf *, unsigned int match_len); -+int nx_match_from_string(const char *, struct ofpbuf *); -+int oxm_match_from_string(const char *, struct ofpbuf *); -+ -+void nx_format_field_name(enum mf_field_id, enum ofp_version, struct ds *); -+ -+char *nxm_parse_reg_move(struct ofpact_reg_move *, const char *) -+ OVS_WARN_UNUSED_RESULT; -+ -+void nxm_format_reg_move(const struct ofpact_reg_move *, struct ds *); -+ -+enum ofperr nxm_reg_move_check(const struct ofpact_reg_move *, -+ const struct match *); -+ -+void nxm_reg_load(const struct mf_subfield *, uint64_t src_data, -+ struct flow *, struct flow_wildcards *); -+ -+char *nxm_parse_stack_action(struct ofpact_stack *, const char *) -+ OVS_WARN_UNUSED_RESULT; -+ -+void nxm_format_stack_push(const struct ofpact_stack *, struct ds *); -+void nxm_format_stack_pop(const struct ofpact_stack *, struct ds *); -+ -+enum ofperr nxm_stack_push_check(const struct ofpact_stack *, -+ const struct match *); -+enum ofperr nxm_stack_pop_check(const struct ofpact_stack *, -+ const struct match *); -+void nx_stack_push(struct ofpbuf *stack, const void *v, uint8_t bytes); -+void nx_stack_push_bottom(struct ofpbuf *stack, const void *v, uint8_t bytes); -+void *nx_stack_pop(struct ofpbuf *stack, uint8_t *bytes); -+ -+void nxm_execute_stack_push(const struct ofpact_stack *, -+ const struct flow *, struct flow_wildcards *, -+ struct ofpbuf *); -+bool nxm_execute_stack_pop(const struct ofpact_stack *, -+ struct flow *, struct flow_wildcards *, -+ struct ofpbuf *); -+ -+ovs_be64 oxm_bitmap_from_mf_bitmap(const struct mf_bitmap *, enum ofp_version); -+struct mf_bitmap oxm_bitmap_to_mf_bitmap(ovs_be64 oxm_bitmap, -+ enum ofp_version); -+struct mf_bitmap oxm_writable_fields(void); -+struct mf_bitmap oxm_matchable_fields(void); -+struct mf_bitmap oxm_maskable_fields(void); -+ -+/* Dealing with the 'ofs_nbits' members in several Nicira extensions. */ -+ -+static inline ovs_be16 -+nxm_encode_ofs_nbits(int ofs, int n_bits) -+{ -+ return htons((ofs << 6) | (n_bits - 1)); -+} -+ -+static inline int -+nxm_decode_ofs(ovs_be16 ofs_nbits) -+{ -+ return ntohs(ofs_nbits) >> 6; -+} -+ -+static inline int -+nxm_decode_n_bits(ovs_be16 ofs_nbits) -+{ -+ return (ntohs(ofs_nbits) & 0x3f) + 1; -+} -+ -+/* This is my guess at the length of a "typical" nx_match, for use in -+ * predicting space requirements. */ -+#define NXM_TYPICAL_LEN 64 -+ -+#endif /* nx-match.h */ -Index: openvswitch-2.17.2/lib/ovs-atomic-clang.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-clang.h -+++ /dev/null -@@ -1,97 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives on Clang. */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#define OVS_ATOMIC_CLANG_IMPL 1 -- --#define ATOMIC(TYPE) _Atomic(TYPE) -- --#define ATOMIC_VAR_INIT(VALUE) (VALUE) -- --#define atomic_init(OBJECT, VALUE) __c11_atomic_init(OBJECT, VALUE) -- --/* Clang hard-codes these exact values internally but does not appear to -- * export any names for them. */ --typedef enum { -- memory_order_relaxed = 0, -- memory_order_consume = 1, -- memory_order_acquire = 2, -- memory_order_release = 3, -- memory_order_acq_rel = 4, -- memory_order_seq_cst = 5 --} memory_order; -- --#define atomic_thread_fence(ORDER) __c11_atomic_thread_fence(ORDER) --#define atomic_signal_fence(ORDER) __c11_atomic_signal_fence(ORDER) -- --#define atomic_store(DST, SRC) \ -- atomic_store_explicit(DST, SRC, memory_order_seq_cst) --#define atomic_store_explicit(DST, SRC, ORDER) \ -- __c11_atomic_store(DST, SRC, ORDER) -- -- --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) --#define atomic_read_explicit(SRC, DST, ORDER) \ -- (*(DST) = __c11_atomic_load(SRC, ORDER), \ -- (void) 0) -- --#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -- atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -- memory_order_seq_cst, \ -- memory_order_seq_cst) --#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -- __c11_atomic_compare_exchange_strong(DST, EXP, SRC, ORD1, ORD2) -- --#define atomic_compare_exchange_weak(DST, EXP, SRC) \ -- atomic_compare_exchange_weak_explicit(DST, EXP, SRC, \ -- memory_order_seq_cst, \ -- memory_order_seq_cst) --#define atomic_compare_exchange_weak_explicit(DST, EXP, SRC, ORD1, ORD2) \ -- __c11_atomic_compare_exchange_weak(DST, EXP, SRC, ORD1, ORD2) -- --#define atomic_exchange(RMW, ARG) \ -- atomic_exchange_explicit(RMW, ARG, memory_order_seq_cst) --#define atomic_exchange_explicit(RMW, ARG, ORDER) \ -- __c11_atomic_exchange(RMW, ARG, ORDER) -- --#define atomic_add(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_sub(RMW, ARG, ORIG) \ -- atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_or(RMW, ARG, ORIG) \ -- atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_xor(RMW, ARG, ORIG) \ -- atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_and(RMW, ARG, ORIG) \ -- atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = __c11_atomic_fetch_add(RMW, ARG, ORDER), (void) 0) --#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = __c11_atomic_fetch_sub(RMW, ARG, ORDER), (void) 0) --#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = __c11_atomic_fetch_or(RMW, ARG, ORDER), (void) 0) --#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = __c11_atomic_fetch_xor(RMW, ARG, ORDER), (void) 0) --#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = __c11_atomic_fetch_and(RMW, ARG, ORDER), (void) 0) -- --#include "ovs-atomic-flag-gcc4.7+.h" -Index: openvswitch-2.17.2/include/internal/ovs-atomic-clang.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-clang.h -@@ -0,0 +1,97 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives on Clang. */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#define OVS_ATOMIC_CLANG_IMPL 1 -+ -+#define ATOMIC(TYPE) _Atomic(TYPE) -+ -+#define ATOMIC_VAR_INIT(VALUE) (VALUE) -+ -+#define atomic_init(OBJECT, VALUE) __c11_atomic_init(OBJECT, VALUE) -+ -+/* Clang hard-codes these exact values internally but does not appear to -+ * export any names for them. */ -+typedef enum { -+ memory_order_relaxed = 0, -+ memory_order_consume = 1, -+ memory_order_acquire = 2, -+ memory_order_release = 3, -+ memory_order_acq_rel = 4, -+ memory_order_seq_cst = 5 -+} memory_order; -+ -+#define atomic_thread_fence(ORDER) __c11_atomic_thread_fence(ORDER) -+#define atomic_signal_fence(ORDER) __c11_atomic_signal_fence(ORDER) -+ -+#define atomic_store(DST, SRC) \ -+ atomic_store_explicit(DST, SRC, memory_order_seq_cst) -+#define atomic_store_explicit(DST, SRC, ORDER) \ -+ __c11_atomic_store(DST, SRC, ORDER) -+ -+ -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ (*(DST) = __c11_atomic_load(SRC, ORDER), \ -+ (void) 0) -+ -+#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -+ atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -+ memory_order_seq_cst, \ -+ memory_order_seq_cst) -+#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -+ __c11_atomic_compare_exchange_strong(DST, EXP, SRC, ORD1, ORD2) -+ -+#define atomic_compare_exchange_weak(DST, EXP, SRC) \ -+ atomic_compare_exchange_weak_explicit(DST, EXP, SRC, \ -+ memory_order_seq_cst, \ -+ memory_order_seq_cst) -+#define atomic_compare_exchange_weak_explicit(DST, EXP, SRC, ORD1, ORD2) \ -+ __c11_atomic_compare_exchange_weak(DST, EXP, SRC, ORD1, ORD2) -+ -+#define atomic_exchange(RMW, ARG) \ -+ atomic_exchange_explicit(RMW, ARG, memory_order_seq_cst) -+#define atomic_exchange_explicit(RMW, ARG, ORDER) \ -+ __c11_atomic_exchange(RMW, ARG, ORDER) -+ -+#define atomic_add(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_sub(RMW, ARG, ORIG) \ -+ atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_or(RMW, ARG, ORIG) \ -+ atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_xor(RMW, ARG, ORIG) \ -+ atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_and(RMW, ARG, ORIG) \ -+ atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = __c11_atomic_fetch_add(RMW, ARG, ORDER), (void) 0) -+#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = __c11_atomic_fetch_sub(RMW, ARG, ORDER), (void) 0) -+#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = __c11_atomic_fetch_or(RMW, ARG, ORDER), (void) 0) -+#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = __c11_atomic_fetch_xor(RMW, ARG, ORDER), (void) 0) -+#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = __c11_atomic_fetch_and(RMW, ARG, ORDER), (void) 0) -+ -+#include "internal/ovs-atomic-flag-gcc4.7+.h" -Index: openvswitch-2.17.2/lib/ovs-atomic-gcc4+.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-gcc4+.h -+++ /dev/null -@@ -1,208 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives on GCC 4.x. */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#include "ovs-atomic-locked.h" --#define OVS_ATOMIC_GCC4P_IMPL 1 -- --#define ATOMIC(TYPE) TYPE -- --#define ATOMIC_BOOL_LOCK_FREE 2 --#define ATOMIC_CHAR_LOCK_FREE 2 --#define ATOMIC_SHORT_LOCK_FREE 2 --#define ATOMIC_INT_LOCK_FREE 2 --#define ATOMIC_LONG_LOCK_FREE (ULONG_MAX <= UINTPTR_MAX ? 2 : 0) --#define ATOMIC_LLONG_LOCK_FREE (ULLONG_MAX <= UINTPTR_MAX ? 2 : 0) --#define ATOMIC_POINTER_LOCK_FREE 2 -- --typedef enum { -- memory_order_relaxed, -- memory_order_consume, -- memory_order_acquire, -- memory_order_release, -- memory_order_acq_rel, -- memory_order_seq_cst --} memory_order; -- --#define IS_LOCKLESS_ATOMIC(OBJECT) (sizeof(OBJECT) <= sizeof(void *)) -- --#define ATOMIC_VAR_INIT(VALUE) VALUE --#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -- --static inline void --atomic_thread_fence(memory_order order) --{ -- if (order != memory_order_relaxed) { -- __sync_synchronize(); -- } --} -- --static inline void --atomic_thread_fence_if_seq_cst(memory_order order) --{ -- if (order == memory_order_seq_cst) { -- __sync_synchronize(); -- } --} -- --static inline void --atomic_signal_fence(memory_order order) --{ -- if (order != memory_order_relaxed) { -- asm volatile("" : : : "memory"); -- } --} -- --#define atomic_is_lock_free(OBJ) \ -- ((void) *(OBJ), \ -- IS_LOCKLESS_ATOMIC(*(OBJ)) ? 2 : 0) -- --#define atomic_store(DST, SRC) \ -- atomic_store_explicit(DST, SRC, memory_order_seq_cst) --#define atomic_store_explicit(DST, SRC, ORDER) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(SRC) src__ = (SRC); \ -- \ -- if (IS_LOCKLESS_ATOMIC(*dst__)) { \ -- atomic_thread_fence(ORDER); \ -- *(typeof(*(DST)) volatile *)dst__ = src__; \ -- atomic_thread_fence_if_seq_cst(ORDER); \ -- } else { \ -- atomic_store_locked(dst__, src__); \ -- } \ -- (void) 0; \ -- }) --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) --#define atomic_read_explicit(SRC, DST, ORDER) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(SRC) src__ = (SRC); \ -- \ -- if (IS_LOCKLESS_ATOMIC(*src__)) { \ -- atomic_thread_fence_if_seq_cst(ORDER); \ -- *dst__ = *(typeof(*(SRC)) volatile *)src__; \ -- } else { \ -- atomic_read_locked(src__, dst__); \ -- } \ -- (void) 0; \ -- }) -- --#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(EXP) expp__ = (EXP); \ -- typeof(SRC) src__ = (SRC); \ -- typeof(SRC) exp__ = *expp__; \ -- typeof(SRC) ret__; \ -- \ -- ret__ = __sync_val_compare_and_swap(dst__, exp__, src__); \ -- if (ret__ != exp__) { \ -- *expp__ = ret__; \ -- } \ -- ret__ == exp__; \ -- }) --#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -- ((void) (ORD1), (void) (ORD2), \ -- atomic_compare_exchange_strong(DST, EXP, SRC)) --#define atomic_compare_exchange_weak \ -- atomic_compare_exchange_strong --#define atomic_compare_exchange_weak_explicit \ -- atomic_compare_exchange_strong_explicit -- --#define atomic_exchange_explicit(DST, SRC, ORDER) \ -- __sync_lock_test_and_set(DST, SRC) --#define atomic_exchange(DST, SRC) \ -- atomic_exchange_explicit(DST, SRC, memory_order_seq_cst) -- --#define atomic_op__(RMW, OP, ARG, ORIG) \ -- ({ \ -- typeof(RMW) rmw__ = (RMW); \ -- typeof(ARG) arg__ = (ARG); \ -- typeof(ORIG) orig__ = (ORIG); \ -- \ -- if (IS_LOCKLESS_ATOMIC(*rmw__)) { \ -- *orig__ = __sync_fetch_and_##OP(rmw__, arg__); \ -- } else { \ -- atomic_op_locked(rmw__, OP, arg__, orig__); \ -- } \ -- (void) 0; \ -- }) -- --#define atomic_add(RMW, ARG, ORIG) atomic_op__(RMW, add, ARG, ORIG) --#define atomic_sub(RMW, ARG, ORIG) atomic_op__(RMW, sub, ARG, ORIG) --#define atomic_or(RMW, ARG, ORIG) atomic_op__(RMW, or, ARG, ORIG) --#define atomic_xor(RMW, ARG, ORIG) atomic_op__(RMW, xor, ARG, ORIG) --#define atomic_and(RMW, ARG, ORIG) atomic_op__(RMW, and, ARG, ORIG) -- --#define atomic_add_explicit(RMW, OPERAND, ORIG, ORDER) \ -- ((void) (ORDER), atomic_add(RMW, OPERAND, ORIG)) --#define atomic_sub_explicit(RMW, OPERAND, ORIG, ORDER) \ -- ((void) (ORDER), atomic_sub(RMW, OPERAND, ORIG)) --#define atomic_or_explicit(RMW, OPERAND, ORIG, ORDER) \ -- ((void) (ORDER), atomic_or(RMW, OPERAND, ORIG)) --#define atomic_xor_explicit(RMW, OPERAND, ORIG, ORDER) \ -- ((void) (ORDER), atomic_xor(RMW, OPERAND, ORIG)) --#define atomic_and_explicit(RMW, OPERAND, ORIG, ORDER) \ -- ((void) (ORDER), atomic_and(RMW, OPERAND, ORIG)) -- --/* atomic_flag */ -- --typedef struct { -- int b; --} atomic_flag; --#define ATOMIC_FLAG_INIT { false } -- --static inline bool --atomic_flag_test_and_set_explicit(volatile atomic_flag *object, -- memory_order order) --{ -- bool old; -- -- /* __sync_lock_test_and_set() by itself is an acquire barrier. -- * For anything higher additional barriers are needed. */ -- if (order > memory_order_acquire) { -- atomic_thread_fence(order); -- } -- old = __sync_lock_test_and_set(&object->b, 1); -- atomic_thread_fence_if_seq_cst(order); -- -- return old; --} -- --#define atomic_flag_test_and_set(FLAG) \ -- atomic_flag_test_and_set_explicit(FLAG, memory_order_seq_cst) -- --static inline void --atomic_flag_clear_explicit(volatile atomic_flag *object, -- memory_order order) --{ -- /* __sync_lock_release() by itself is a release barrier. For -- * anything else additional barrier may be needed. */ -- if (order != memory_order_release) { -- atomic_thread_fence(order); -- } -- __sync_lock_release(&object->b); -- atomic_thread_fence_if_seq_cst(order); --} -- --#define atomic_flag_clear(FLAG) \ -- atomic_flag_clear_explicit(FLAG, memory_order_seq_cst) -Index: openvswitch-2.17.2/include/internal/ovs-atomic-gcc4+.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-gcc4+.h -@@ -0,0 +1,208 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives on GCC 4.x. */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#include "internal/ovs-atomic-locked.h" -+#define OVS_ATOMIC_GCC4P_IMPL 1 -+ -+#define ATOMIC(TYPE) TYPE -+ -+#define ATOMIC_BOOL_LOCK_FREE 2 -+#define ATOMIC_CHAR_LOCK_FREE 2 -+#define ATOMIC_SHORT_LOCK_FREE 2 -+#define ATOMIC_INT_LOCK_FREE 2 -+#define ATOMIC_LONG_LOCK_FREE (ULONG_MAX <= UINTPTR_MAX ? 2 : 0) -+#define ATOMIC_LLONG_LOCK_FREE (ULLONG_MAX <= UINTPTR_MAX ? 2 : 0) -+#define ATOMIC_POINTER_LOCK_FREE 2 -+ -+typedef enum { -+ memory_order_relaxed, -+ memory_order_consume, -+ memory_order_acquire, -+ memory_order_release, -+ memory_order_acq_rel, -+ memory_order_seq_cst -+} memory_order; -+ -+#define IS_LOCKLESS_ATOMIC(OBJECT) (sizeof(OBJECT) <= sizeof(void *)) -+ -+#define ATOMIC_VAR_INIT(VALUE) VALUE -+#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -+ -+static inline void -+atomic_thread_fence(memory_order order) -+{ -+ if (order != memory_order_relaxed) { -+ __sync_synchronize(); -+ } -+} -+ -+static inline void -+atomic_thread_fence_if_seq_cst(memory_order order) -+{ -+ if (order == memory_order_seq_cst) { -+ __sync_synchronize(); -+ } -+} -+ -+static inline void -+atomic_signal_fence(memory_order order) -+{ -+ if (order != memory_order_relaxed) { -+ asm volatile("" : : : "memory"); -+ } -+} -+ -+#define atomic_is_lock_free(OBJ) \ -+ ((void) *(OBJ), \ -+ IS_LOCKLESS_ATOMIC(*(OBJ)) ? 2 : 0) -+ -+#define atomic_store(DST, SRC) \ -+ atomic_store_explicit(DST, SRC, memory_order_seq_cst) -+#define atomic_store_explicit(DST, SRC, ORDER) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(SRC) src__ = (SRC); \ -+ \ -+ if (IS_LOCKLESS_ATOMIC(*dst__)) { \ -+ atomic_thread_fence(ORDER); \ -+ *(typeof(*(DST)) volatile *)dst__ = src__; \ -+ atomic_thread_fence_if_seq_cst(ORDER); \ -+ } else { \ -+ atomic_store_locked(dst__, src__); \ -+ } \ -+ (void) 0; \ -+ }) -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(SRC) src__ = (SRC); \ -+ \ -+ if (IS_LOCKLESS_ATOMIC(*src__)) { \ -+ atomic_thread_fence_if_seq_cst(ORDER); \ -+ *dst__ = *(typeof(*(SRC)) volatile *)src__; \ -+ } else { \ -+ atomic_read_locked(src__, dst__); \ -+ } \ -+ (void) 0; \ -+ }) -+ -+#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(EXP) expp__ = (EXP); \ -+ typeof(SRC) src__ = (SRC); \ -+ typeof(SRC) exp__ = *expp__; \ -+ typeof(SRC) ret__; \ -+ \ -+ ret__ = __sync_val_compare_and_swap(dst__, exp__, src__); \ -+ if (ret__ != exp__) { \ -+ *expp__ = ret__; \ -+ } \ -+ ret__ == exp__; \ -+ }) -+#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -+ ((void) (ORD1), (void) (ORD2), \ -+ atomic_compare_exchange_strong(DST, EXP, SRC)) -+#define atomic_compare_exchange_weak \ -+ atomic_compare_exchange_strong -+#define atomic_compare_exchange_weak_explicit \ -+ atomic_compare_exchange_strong_explicit -+ -+#define atomic_exchange_explicit(DST, SRC, ORDER) \ -+ __sync_lock_test_and_set(DST, SRC) -+#define atomic_exchange(DST, SRC) \ -+ atomic_exchange_explicit(DST, SRC, memory_order_seq_cst) -+ -+#define atomic_op__(RMW, OP, ARG, ORIG) \ -+ ({ \ -+ typeof(RMW) rmw__ = (RMW); \ -+ typeof(ARG) arg__ = (ARG); \ -+ typeof(ORIG) orig__ = (ORIG); \ -+ \ -+ if (IS_LOCKLESS_ATOMIC(*rmw__)) { \ -+ *orig__ = __sync_fetch_and_##OP(rmw__, arg__); \ -+ } else { \ -+ atomic_op_locked(rmw__, OP, arg__, orig__); \ -+ } \ -+ (void) 0; \ -+ }) -+ -+#define atomic_add(RMW, ARG, ORIG) atomic_op__(RMW, add, ARG, ORIG) -+#define atomic_sub(RMW, ARG, ORIG) atomic_op__(RMW, sub, ARG, ORIG) -+#define atomic_or(RMW, ARG, ORIG) atomic_op__(RMW, or, ARG, ORIG) -+#define atomic_xor(RMW, ARG, ORIG) atomic_op__(RMW, xor, ARG, ORIG) -+#define atomic_and(RMW, ARG, ORIG) atomic_op__(RMW, and, ARG, ORIG) -+ -+#define atomic_add_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_add(RMW, OPERAND, ORIG)) -+#define atomic_sub_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_sub(RMW, OPERAND, ORIG)) -+#define atomic_or_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_or(RMW, OPERAND, ORIG)) -+#define atomic_xor_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_xor(RMW, OPERAND, ORIG)) -+#define atomic_and_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_and(RMW, OPERAND, ORIG)) -+ -+/* atomic_flag */ -+ -+typedef struct { -+ int b; -+} atomic_flag; -+#define ATOMIC_FLAG_INIT { false } -+ -+static inline bool -+atomic_flag_test_and_set_explicit(volatile atomic_flag *object, -+ memory_order order) -+{ -+ bool old; -+ -+ /* __sync_lock_test_and_set() by itself is an acquire barrier. -+ * For anything higher additional barriers are needed. */ -+ if (order > memory_order_acquire) { -+ atomic_thread_fence(order); -+ } -+ old = __sync_lock_test_and_set(&object->b, 1); -+ atomic_thread_fence_if_seq_cst(order); -+ -+ return old; -+} -+ -+#define atomic_flag_test_and_set(FLAG) \ -+ atomic_flag_test_and_set_explicit(FLAG, memory_order_seq_cst) -+ -+static inline void -+atomic_flag_clear_explicit(volatile atomic_flag *object, -+ memory_order order) -+{ -+ /* __sync_lock_release() by itself is a release barrier. For -+ * anything else additional barrier may be needed. */ -+ if (order != memory_order_release) { -+ atomic_thread_fence(order); -+ } -+ __sync_lock_release(&object->b); -+ atomic_thread_fence_if_seq_cst(order); -+} -+ -+#define atomic_flag_clear(FLAG) \ -+ atomic_flag_clear_explicit(FLAG, memory_order_seq_cst) -Index: openvswitch-2.17.2/lib/ovs-atomic-gcc4.7+.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-gcc4.7+.h -+++ /dev/null -@@ -1,91 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives on GCC 4.7 and later. */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#define ATOMIC(TYPE) TYPE -- --typedef enum { -- memory_order_relaxed = __ATOMIC_RELAXED, -- memory_order_consume = __ATOMIC_CONSUME, -- memory_order_acquire = __ATOMIC_ACQUIRE, -- memory_order_release = __ATOMIC_RELEASE, -- memory_order_acq_rel = __ATOMIC_ACQ_REL, -- memory_order_seq_cst = __ATOMIC_SEQ_CST --} memory_order; -- --#define ATOMIC_VAR_INIT(VALUE) (VALUE) --#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -- --#define atomic_thread_fence __atomic_thread_fence --#define atomic_signal_fence __atomic_signal_fence --#define atomic_is_lock_free __atomic_is_lock_free -- --#define atomic_store(DST, SRC) \ -- atomic_store_explicit(DST, SRC, memory_order_seq_cst) --#define atomic_store_explicit __atomic_store_n -- --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) --#define atomic_read_explicit(SRC, DST, ORDER) \ -- (*(DST) = __atomic_load_n(SRC, ORDER), \ -- (void) 0) -- --#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -- atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -- memory_order_seq_cst, \ -- memory_order_seq_cst) --#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -- __atomic_compare_exchange_n(DST, EXP, SRC, false, ORD1, ORD2) -- --#define atomic_compare_exchange_weak(DST, EXP, SRC) \ -- atomic_compare_exchange_weak_explicit(DST, EXP, SRC, \ -- memory_order_seq_cst, \ -- memory_order_seq_cst) --#define atomic_compare_exchange_weak_explicit(DST, EXP, SRC, ORD1, ORD2) \ -- __atomic_compare_exchange_n(DST, EXP, SRC, true, ORD1, ORD2) -- --#define atomic_exchange_explicit(DST, SRC, ORDER) \ -- __atomic_exchange_n(DST, SRC, ORDER) --#define atomic_exchange(DST, SRC) \ -- atomic_exchange_explicit(DST, SRC, memory_order_seq_cst) -- --#define atomic_add(RMW, OPERAND, ORIG) \ -- atomic_add_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) --#define atomic_sub(RMW, OPERAND, ORIG) \ -- atomic_sub_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) --#define atomic_or(RMW, OPERAND, ORIG) \ -- atomic_or_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) --#define atomic_xor(RMW, OPERAND, ORIG) \ -- atomic_xor_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) --#define atomic_and(RMW, OPERAND, ORIG) \ -- atomic_and_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) -- --#define atomic_add_explicit(RMW, OPERAND, ORIG, ORDER) \ -- (*(ORIG) = __atomic_fetch_add(RMW, OPERAND, ORDER), (void) 0) --#define atomic_sub_explicit(RMW, OPERAND, ORIG, ORDER) \ -- (*(ORIG) = __atomic_fetch_sub(RMW, OPERAND, ORDER), (void) 0) --#define atomic_or_explicit(RMW, OPERAND, ORIG, ORDER) \ -- (*(ORIG) = __atomic_fetch_or(RMW, OPERAND, ORDER), (void) 0) --#define atomic_xor_explicit(RMW, OPERAND, ORIG, ORDER) \ -- (*(ORIG) = __atomic_fetch_xor(RMW, OPERAND, ORDER), (void) 0) --#define atomic_and_explicit(RMW, OPERAND, ORIG, ORDER) \ -- (*(ORIG) = __atomic_fetch_and(RMW, OPERAND, ORDER), (void) 0) -- --#include "ovs-atomic-flag-gcc4.7+.h" -Index: openvswitch-2.17.2/include/internal/ovs-atomic-gcc4.7+.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-gcc4.7+.h -@@ -0,0 +1,91 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives on GCC 4.7 and later. */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#define ATOMIC(TYPE) TYPE -+ -+typedef enum { -+ memory_order_relaxed = __ATOMIC_RELAXED, -+ memory_order_consume = __ATOMIC_CONSUME, -+ memory_order_acquire = __ATOMIC_ACQUIRE, -+ memory_order_release = __ATOMIC_RELEASE, -+ memory_order_acq_rel = __ATOMIC_ACQ_REL, -+ memory_order_seq_cst = __ATOMIC_SEQ_CST -+} memory_order; -+ -+#define ATOMIC_VAR_INIT(VALUE) (VALUE) -+#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -+ -+#define atomic_thread_fence __atomic_thread_fence -+#define atomic_signal_fence __atomic_signal_fence -+#define atomic_is_lock_free __atomic_is_lock_free -+ -+#define atomic_store(DST, SRC) \ -+ atomic_store_explicit(DST, SRC, memory_order_seq_cst) -+#define atomic_store_explicit __atomic_store_n -+ -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ (*(DST) = __atomic_load_n(SRC, ORDER), \ -+ (void) 0) -+ -+#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -+ atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -+ memory_order_seq_cst, \ -+ memory_order_seq_cst) -+#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -+ __atomic_compare_exchange_n(DST, EXP, SRC, false, ORD1, ORD2) -+ -+#define atomic_compare_exchange_weak(DST, EXP, SRC) \ -+ atomic_compare_exchange_weak_explicit(DST, EXP, SRC, \ -+ memory_order_seq_cst, \ -+ memory_order_seq_cst) -+#define atomic_compare_exchange_weak_explicit(DST, EXP, SRC, ORD1, ORD2) \ -+ __atomic_compare_exchange_n(DST, EXP, SRC, true, ORD1, ORD2) -+ -+#define atomic_exchange_explicit(DST, SRC, ORDER) \ -+ __atomic_exchange_n(DST, SRC, ORDER) -+#define atomic_exchange(DST, SRC) \ -+ atomic_exchange_explicit(DST, SRC, memory_order_seq_cst) -+ -+#define atomic_add(RMW, OPERAND, ORIG) \ -+ atomic_add_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) -+#define atomic_sub(RMW, OPERAND, ORIG) \ -+ atomic_sub_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) -+#define atomic_or(RMW, OPERAND, ORIG) \ -+ atomic_or_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) -+#define atomic_xor(RMW, OPERAND, ORIG) \ -+ atomic_xor_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) -+#define atomic_and(RMW, OPERAND, ORIG) \ -+ atomic_and_explicit(RMW, OPERAND, ORIG, memory_order_seq_cst) -+ -+#define atomic_add_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ (*(ORIG) = __atomic_fetch_add(RMW, OPERAND, ORDER), (void) 0) -+#define atomic_sub_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ (*(ORIG) = __atomic_fetch_sub(RMW, OPERAND, ORDER), (void) 0) -+#define atomic_or_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ (*(ORIG) = __atomic_fetch_or(RMW, OPERAND, ORDER), (void) 0) -+#define atomic_xor_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ (*(ORIG) = __atomic_fetch_xor(RMW, OPERAND, ORDER), (void) 0) -+#define atomic_and_explicit(RMW, OPERAND, ORIG, ORDER) \ -+ (*(ORIG) = __atomic_fetch_and(RMW, OPERAND, ORDER), (void) 0) -+ -+#include "internal/ovs-atomic-flag-gcc4.7+.h" -Index: openvswitch-2.17.2/lib/ovs-atomic-locked.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-locked.c -+++ /dev/null -@@ -1,58 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#include -- --#include "ovs-atomic.h" --#include "hash.h" --#include "ovs-thread.h" -- --#ifdef OVS_ATOMIC_LOCKED_IMPL --static struct ovs_mutex * --mutex_for_pointer(void *p) --{ -- OVS_ALIGNED_STRUCT(CACHE_LINE_SIZE, aligned_mutex) { -- struct ovs_mutex mutex; -- char pad[PAD_SIZE(sizeof(struct ovs_mutex), CACHE_LINE_SIZE)]; -- }; -- -- static struct aligned_mutex atomic_mutexes[] = { --#define MUTEX_INIT { .mutex = OVS_MUTEX_INITIALIZER } --#define MUTEX_INIT4 MUTEX_INIT, MUTEX_INIT, MUTEX_INIT, MUTEX_INIT --#define MUTEX_INIT16 MUTEX_INIT4, MUTEX_INIT4, MUTEX_INIT4, MUTEX_INIT4 -- MUTEX_INIT16, MUTEX_INIT16, -- }; -- BUILD_ASSERT_DECL(IS_POW2(ARRAY_SIZE(atomic_mutexes))); -- -- uint32_t hash = hash_pointer(p, 0); -- uint32_t indx = hash & (ARRAY_SIZE(atomic_mutexes) - 1); -- return &atomic_mutexes[indx].mutex; --} -- --void --atomic_lock__(void *p) -- OVS_ACQUIRES(mutex_for_pointer(p)) --{ -- ovs_mutex_lock(mutex_for_pointer(p)); --} -- --void --atomic_unlock__(void *p) -- OVS_RELEASES(mutex_for_pointer(p)) --{ -- ovs_mutex_unlock(mutex_for_pointer(p)); --} --#endif /* OVS_ATOMIC_LOCKED_IMPL */ -Index: openvswitch-2.17.2/include/internal/ovs-atomic-locked.c -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-locked.c -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#include -+ -+#include "openvswitch/ovs-atomic.h" -+#include "internal/hash.h" -+#include "openvswitch/ovs-thread.h" -+ -+#ifdef OVS_ATOMIC_LOCKED_IMPL -+static struct ovs_mutex * -+mutex_for_pointer(void *p) -+{ -+ OVS_ALIGNED_STRUCT(CACHE_LINE_SIZE, aligned_mutex) { -+ struct ovs_mutex mutex; -+ char pad[PAD_SIZE(sizeof(struct ovs_mutex), CACHE_LINE_SIZE)]; -+ }; -+ -+ static struct aligned_mutex atomic_mutexes[] = { -+#define MUTEX_INIT { .mutex = OVS_MUTEX_INITIALIZER } -+#define MUTEX_INIT4 MUTEX_INIT, MUTEX_INIT, MUTEX_INIT, MUTEX_INIT -+#define MUTEX_INIT16 MUTEX_INIT4, MUTEX_INIT4, MUTEX_INIT4, MUTEX_INIT4 -+ MUTEX_INIT16, MUTEX_INIT16, -+ }; -+ BUILD_ASSERT_DECL(IS_POW2(ARRAY_SIZE(atomic_mutexes))); -+ -+ uint32_t hash = hash_pointer(p, 0); -+ uint32_t indx = hash & (ARRAY_SIZE(atomic_mutexes) - 1); -+ return &atomic_mutexes[indx].mutex; -+} -+ -+void -+atomic_lock__(void *p) -+ OVS_ACQUIRES(mutex_for_pointer(p)) -+{ -+ ovs_mutex_lock(mutex_for_pointer(p)); -+} -+ -+void -+atomic_unlock__(void *p) -+ OVS_RELEASES(mutex_for_pointer(p)) -+{ -+ ovs_mutex_unlock(mutex_for_pointer(p)); -+} -+#endif /* OVS_ATOMIC_LOCKED_IMPL */ -Index: openvswitch-2.17.2/lib/ovs-atomic-pthreads.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-pthreads.h -+++ /dev/null -@@ -1,145 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives using pthreads. */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#include "ovs-atomic-locked.h" -- --#define OVS_ATOMIC_PTHREADS_IMPL 1 -- --#define ATOMIC(TYPE) TYPE -- --#define ATOMIC_BOOL_LOCK_FREE 0 --#define ATOMIC_CHAR_LOCK_FREE 0 --#define ATOMIC_SHORT_LOCK_FREE 0 --#define ATOMIC_INT_LOCK_FREE 0 --#define ATOMIC_LONG_LOCK_FREE 0 --#define ATOMIC_LLONG_LOCK_FREE 0 --#define ATOMIC_POINTER_LOCK_FREE 0 -- --typedef enum { -- memory_order_relaxed, -- memory_order_consume, -- memory_order_acquire, -- memory_order_release, -- memory_order_acq_rel, -- memory_order_seq_cst --} memory_order; -- --#define ATOMIC_VAR_INIT(VALUE) (VALUE) --#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -- --static inline void --atomic_thread_fence(memory_order order OVS_UNUSED) --{ -- /* Nothing to do. */ --} -- --static inline void --atomic_signal_fence(memory_order order OVS_UNUSED) --{ -- /* Nothing to do. */ --} -- --#define atomic_is_lock_free(OBJ) false -- --#define atomic_store(DST, SRC) atomic_store_locked(DST, SRC) --#define atomic_store_explicit(DST, SRC, ORDER) \ -- ((void) (ORDER), atomic_store(DST, SRC)) -- --#define atomic_read(SRC, DST) atomic_read_locked(SRC, DST) --#define atomic_read_explicit(SRC, DST, ORDER) \ -- ((void) (ORDER), atomic_read(SRC, DST)) -- --#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -- atomic_compare_exchange_locked(DST, EXP, SRC) --#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -- ((void) (ORD1), (void) (ORD2), \ -- atomic_compare_exchange_strong(DST, EXP, SRC)) --#define atomic_compare_exchange_weak \ -- atomic_compare_exchange_strong --#define atomic_compare_exchange_weak_explicit \ -- atomic_compare_exchange_strong_explicit -- --#define atomic_exchange(DST, SRC) \ -- atomic_exchange_locked(DST, SRC) --#define atomic_exchange_explicit(DST, SRC, ORDER) \ -- ((void) (ORDER), atomic_exchange(DST, SRC)) -- --#define atomic_add(RMW, ARG, ORIG) atomic_op_locked(RMW, add, ARG, ORIG) --#define atomic_sub(RMW, ARG, ORIG) atomic_op_locked(RMW, sub, ARG, ORIG) --#define atomic_or( RMW, ARG, ORIG) atomic_op_locked(RMW, or, ARG, ORIG) --#define atomic_xor(RMW, ARG, ORIG) atomic_op_locked(RMW, xor, ARG, ORIG) --#define atomic_and(RMW, ARG, ORIG) atomic_op_locked(RMW, and, ARG, ORIG) -- --#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -- ((void) (ORDER), atomic_add(RMW, ARG, ORIG)) --#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -- ((void) (ORDER), atomic_sub(RMW, ARG, ORIG)) --#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -- ((void) (ORDER), atomic_or(RMW, ARG, ORIG)) --#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -- ((void) (ORDER), atomic_xor(RMW, ARG, ORIG)) --#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -- ((void) (ORDER), atomic_and(RMW, ARG, ORIG)) -- --/* atomic_flag */ -- --typedef struct { -- bool b; --} atomic_flag; --#define ATOMIC_FLAG_INIT { false } -- --static inline bool --atomic_flag_test_and_set(volatile atomic_flag *flag_) --{ -- atomic_flag *flag = CONST_CAST(atomic_flag *, flag_); -- bool old_value; -- -- atomic_lock__(flag); -- old_value = flag->b; -- flag->b = true; -- atomic_unlock__(flag); -- -- return old_value; --} -- --static inline bool --atomic_flag_test_and_set_explicit(volatile atomic_flag *flag, -- memory_order order OVS_UNUSED) --{ -- return atomic_flag_test_and_set(flag); --} -- --static inline void --atomic_flag_clear(volatile atomic_flag *flag_) --{ -- atomic_flag *flag = CONST_CAST(atomic_flag *, flag_); -- -- atomic_lock__(flag); -- flag->b = false; -- atomic_unlock__(flag); --} -- --static inline void --atomic_flag_clear_explicit(volatile atomic_flag *flag, -- memory_order order OVS_UNUSED) --{ -- atomic_flag_clear(flag); --} -Index: openvswitch-2.17.2/include/internal/ovs-atomic-pthreads.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-pthreads.h -@@ -0,0 +1,145 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives using pthreads. */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#include "internal/ovs-atomic-locked.h" -+ -+#define OVS_ATOMIC_PTHREADS_IMPL 1 -+ -+#define ATOMIC(TYPE) TYPE -+ -+#define ATOMIC_BOOL_LOCK_FREE 0 -+#define ATOMIC_CHAR_LOCK_FREE 0 -+#define ATOMIC_SHORT_LOCK_FREE 0 -+#define ATOMIC_INT_LOCK_FREE 0 -+#define ATOMIC_LONG_LOCK_FREE 0 -+#define ATOMIC_LLONG_LOCK_FREE 0 -+#define ATOMIC_POINTER_LOCK_FREE 0 -+ -+typedef enum { -+ memory_order_relaxed, -+ memory_order_consume, -+ memory_order_acquire, -+ memory_order_release, -+ memory_order_acq_rel, -+ memory_order_seq_cst -+} memory_order; -+ -+#define ATOMIC_VAR_INIT(VALUE) (VALUE) -+#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -+ -+static inline void -+atomic_thread_fence(memory_order order OVS_UNUSED) -+{ -+ /* Nothing to do. */ -+} -+ -+static inline void -+atomic_signal_fence(memory_order order OVS_UNUSED) -+{ -+ /* Nothing to do. */ -+} -+ -+#define atomic_is_lock_free(OBJ) false -+ -+#define atomic_store(DST, SRC) atomic_store_locked(DST, SRC) -+#define atomic_store_explicit(DST, SRC, ORDER) \ -+ ((void) (ORDER), atomic_store(DST, SRC)) -+ -+#define atomic_read(SRC, DST) atomic_read_locked(SRC, DST) -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ ((void) (ORDER), atomic_read(SRC, DST)) -+ -+#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -+ atomic_compare_exchange_locked(DST, EXP, SRC) -+#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -+ ((void) (ORD1), (void) (ORD2), \ -+ atomic_compare_exchange_strong(DST, EXP, SRC)) -+#define atomic_compare_exchange_weak \ -+ atomic_compare_exchange_strong -+#define atomic_compare_exchange_weak_explicit \ -+ atomic_compare_exchange_strong_explicit -+ -+#define atomic_exchange(DST, SRC) \ -+ atomic_exchange_locked(DST, SRC) -+#define atomic_exchange_explicit(DST, SRC, ORDER) \ -+ ((void) (ORDER), atomic_exchange(DST, SRC)) -+ -+#define atomic_add(RMW, ARG, ORIG) atomic_op_locked(RMW, add, ARG, ORIG) -+#define atomic_sub(RMW, ARG, ORIG) atomic_op_locked(RMW, sub, ARG, ORIG) -+#define atomic_or( RMW, ARG, ORIG) atomic_op_locked(RMW, or, ARG, ORIG) -+#define atomic_xor(RMW, ARG, ORIG) atomic_op_locked(RMW, xor, ARG, ORIG) -+#define atomic_and(RMW, ARG, ORIG) atomic_op_locked(RMW, and, ARG, ORIG) -+ -+#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_add(RMW, ARG, ORIG)) -+#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_sub(RMW, ARG, ORIG)) -+#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_or(RMW, ARG, ORIG)) -+#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_xor(RMW, ARG, ORIG)) -+#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -+ ((void) (ORDER), atomic_and(RMW, ARG, ORIG)) -+ -+/* atomic_flag */ -+ -+typedef struct { -+ bool b; -+} atomic_flag; -+#define ATOMIC_FLAG_INIT { false } -+ -+static inline bool -+atomic_flag_test_and_set(volatile atomic_flag *flag_) -+{ -+ atomic_flag *flag = CONST_CAST(atomic_flag *, flag_); -+ bool old_value; -+ -+ atomic_lock__(flag); -+ old_value = flag->b; -+ flag->b = true; -+ atomic_unlock__(flag); -+ -+ return old_value; -+} -+ -+static inline bool -+atomic_flag_test_and_set_explicit(volatile atomic_flag *flag, -+ memory_order order OVS_UNUSED) -+{ -+ return atomic_flag_test_and_set(flag); -+} -+ -+static inline void -+atomic_flag_clear(volatile atomic_flag *flag_) -+{ -+ atomic_flag *flag = CONST_CAST(atomic_flag *, flag_); -+ -+ atomic_lock__(flag); -+ flag->b = false; -+ atomic_unlock__(flag); -+} -+ -+static inline void -+atomic_flag_clear_explicit(volatile atomic_flag *flag, -+ memory_order order OVS_UNUSED) -+{ -+ atomic_flag_clear(flag); -+} -Index: openvswitch-2.17.2/lib/packets.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/packets.h -+++ /dev/null -@@ -1,1671 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef PACKETS_H --#define PACKETS_H 1 -- --#include --#include --#include --#include --#include "openvswitch/compiler.h" --#include "openvswitch/geneve.h" --#include "openvswitch/packets.h" --#include "openvswitch/types.h" --#include "openvswitch/nsh.h" --#include "odp-netlink.h" --#include "random.h" --#include "hash.h" --#include "tun-metadata.h" --#include "unaligned.h" --#include "util.h" --#include "timeval.h" -- --struct dp_packet; --struct conn; --struct ds; -- --/* Purely internal to OVS userspace. These flags should never be exposed to -- * the outside world and so aren't included in the flags mask. */ -- --/* Tunnel information is in userspace datapath format. */ --#define FLOW_TNL_F_UDPIF (1 << 4) -- --static inline bool ipv6_addr_is_set(const struct in6_addr *addr); -- --static inline bool --flow_tnl_dst_is_set(const struct flow_tnl *tnl) --{ -- return tnl->ip_dst || ipv6_addr_is_set(&tnl->ipv6_dst); --} -- --static inline bool --flow_tnl_src_is_set(const struct flow_tnl *tnl) --{ -- return tnl->ip_src || ipv6_addr_is_set(&tnl->ipv6_src); --} -- --struct in6_addr flow_tnl_dst(const struct flow_tnl *tnl); --struct in6_addr flow_tnl_src(const struct flow_tnl *tnl); -- --/* Returns an offset to 'src' covering all the meaningful fields in 'src'. */ --static inline size_t --flow_tnl_size(const struct flow_tnl *src) --{ -- if (!flow_tnl_dst_is_set(src)) { -- /* Covers ip_dst and ipv6_dst only. */ -- return offsetof(struct flow_tnl, ip_src); -- } -- if (src->flags & FLOW_TNL_F_UDPIF) { -- /* Datapath format, cover all options we have. */ -- return offsetof(struct flow_tnl, metadata.opts) -- + src->metadata.present.len; -- } -- if (!src->metadata.present.map) { -- /* No TLVs, opts is irrelevant. */ -- return offsetof(struct flow_tnl, metadata.opts); -- } -- /* Have decoded TLVs, opts is relevant. */ -- return sizeof *src; --} -- --/* Copy flow_tnl, but avoid copying unused portions of tun_metadata. Unused -- * data in 'dst' is NOT cleared, so this must not be used in cases where the -- * uninitialized portion may be hashed over. */ --static inline void --flow_tnl_copy__(struct flow_tnl *dst, const struct flow_tnl *src) --{ -- memcpy(dst, src, flow_tnl_size(src)); --} -- --static inline bool --flow_tnl_equal(const struct flow_tnl *a, const struct flow_tnl *b) --{ -- size_t a_size = flow_tnl_size(a); -- -- return a_size == flow_tnl_size(b) && !memcmp(a, b, a_size); --} -- --/* Datapath packet metadata */ --struct pkt_metadata { --PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0, -- uint32_t recirc_id; /* Recirculation id carried with the -- recirculating packets. 0 for packets -- received from the wire. */ -- uint32_t dp_hash; /* hash value computed by the recirculation -- action. */ -- uint32_t skb_priority; /* Packet priority for QoS. */ -- uint32_t pkt_mark; /* Packet mark. */ -- uint8_t ct_state; /* Connection state. */ -- bool ct_orig_tuple_ipv6; -- uint16_t ct_zone; /* Connection zone. */ -- uint32_t ct_mark; /* Connection mark. */ -- ovs_u128 ct_label; /* Connection label. */ -- union flow_in_port in_port; /* Input port. */ -- odp_port_t orig_in_port; /* Originating in_port for tunneled packets */ -- struct conn *conn; /* Cached conntrack connection. */ -- bool reply; /* True if reply direction. */ -- bool icmp_related; /* True if ICMP related. */ --); -- --PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline1, -- union { /* Populated only for non-zero 'ct_state'. */ -- struct ovs_key_ct_tuple_ipv4 ipv4; -- struct ovs_key_ct_tuple_ipv6 ipv6; /* Used only if */ -- } ct_orig_tuple; /* 'ct_orig_tuple_ipv6' is set */ --); -- --PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline2, -- struct flow_tnl tunnel; /* Encapsulating tunnel parameters. Note that -- * if 'ip_dst' == 0, the rest of the fields may -- * be uninitialized. */ --); --}; -- --BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline0) == 0); --BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline1) == -- CACHE_LINE_SIZE); --BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline2) == -- 2 * CACHE_LINE_SIZE); -- --static inline void --pkt_metadata_init_tnl(struct pkt_metadata *md) --{ -- odp_port_t orig_in_port; -- -- /* Zero up through the tunnel metadata options. The length and table -- * are before this and as long as they are empty, the options won't -- * be looked at. Keep the orig_in_port field. */ -- orig_in_port = md->in_port.odp_port; -- memset(md, 0, offsetof(struct pkt_metadata, tunnel.metadata.opts)); -- md->orig_in_port = orig_in_port; --} -- --static inline void --pkt_metadata_init_conn(struct pkt_metadata *md) --{ -- md->conn = NULL; --} -- --static inline void --pkt_metadata_init(struct pkt_metadata *md, odp_port_t port) --{ -- /* This is called for every packet in userspace datapath and affects -- * performance if all the metadata is initialized. Hence, fields should -- * only be zeroed out when necessary. -- * -- * Initialize only till ct_state. Once the ct_state is zeroed out rest -- * of ct fields will not be looked at unless ct_state != 0. -- */ -- memset(md, 0, offsetof(struct pkt_metadata, ct_orig_tuple_ipv6)); -- -- /* It can be expensive to zero out all of the tunnel metadata. However, -- * we can just zero out ip_dst and the rest of the data will never be -- * looked at. */ -- md->tunnel.ip_dst = 0; -- md->tunnel.ipv6_dst = in6addr_any; -- md->in_port.odp_port = port; -- md->orig_in_port = port; -- md->conn = NULL; --} -- --/* This function prefetches the cachelines touched by pkt_metadata_init() -- * and pkt_metadata_init_tnl(). For performance reasons the two functions -- * should be kept in sync. */ --static inline void --pkt_metadata_prefetch_init(struct pkt_metadata *md) --{ -- /* Prefetch cacheline0 as members till ct_state and odp_port will -- * be initialized later in pkt_metadata_init(). */ -- OVS_PREFETCH(md->cacheline0); -- -- /* Prefetch cacheline1 as members of this cacheline will be zeroed out -- * in pkt_metadata_init_tnl(). */ -- OVS_PREFETCH(md->cacheline1); -- -- /* Prefetch cachline2 as ip_dst & ipv6_dst fields will be initialized. */ -- OVS_PREFETCH(md->cacheline2); --} -- --bool dpid_from_string(const char *s, uint64_t *dpidp); -- --#define ETH_ADDR_LEN 6 -- --static const struct eth_addr eth_addr_broadcast OVS_UNUSED -- = ETH_ADDR_C(ff,ff,ff,ff,ff,ff); -- --static const struct eth_addr eth_addr_exact OVS_UNUSED -- = ETH_ADDR_C(ff,ff,ff,ff,ff,ff); -- --static const struct eth_addr eth_addr_zero OVS_UNUSED -- = ETH_ADDR_C(00,00,00,00,00,00); --static const struct eth_addr64 eth_addr64_zero OVS_UNUSED -- = ETH_ADDR64_C(00,00,00,00,00,00,00,00); -- --static const struct eth_addr eth_addr_stp OVS_UNUSED -- = ETH_ADDR_C(01,80,c2,00,00,00); -- --static const struct eth_addr eth_addr_lacp OVS_UNUSED -- = ETH_ADDR_C(01,80,c2,00,00,02); -- --static const struct eth_addr eth_addr_bfd OVS_UNUSED -- = ETH_ADDR_C(00,23,20,00,00,01); -- --static inline bool eth_addr_is_broadcast(const struct eth_addr a) --{ -- return (a.be16[0] & a.be16[1] & a.be16[2]) == htons(0xffff); --} -- --static inline bool eth_addr_is_multicast(const struct eth_addr a) --{ -- return a.ea[0] & 1; --} -- --static inline bool eth_addr_is_local(const struct eth_addr a) --{ -- /* Local if it is either a locally administered address or a Nicira random -- * address. */ -- return a.ea[0] & 2 -- || (a.be16[0] == htons(0x0023) -- && (a.be16[1] & htons(0xff80)) == htons(0x2080)); --} --static inline bool eth_addr_is_zero(const struct eth_addr a) --{ -- return !(a.be16[0] | a.be16[1] | a.be16[2]); --} --static inline bool eth_addr64_is_zero(const struct eth_addr64 a) --{ -- return !(a.be16[0] | a.be16[1] | a.be16[2] | a.be16[3]); --} -- --static inline int eth_mask_is_exact(const struct eth_addr a) --{ -- return (a.be16[0] & a.be16[1] & a.be16[2]) == htons(0xffff); --} -- --static inline int eth_addr_compare_3way(const struct eth_addr a, -- const struct eth_addr b) --{ -- return memcmp(&a, &b, sizeof a); --} --static inline int eth_addr64_compare_3way(const struct eth_addr64 a, -- const struct eth_addr64 b) --{ -- return memcmp(&a, &b, sizeof a); --} -- --static inline bool eth_addr_equals(const struct eth_addr a, -- const struct eth_addr b) --{ -- return !eth_addr_compare_3way(a, b); --} --static inline bool eth_addr64_equals(const struct eth_addr64 a, -- const struct eth_addr64 b) --{ -- return !eth_addr64_compare_3way(a, b); --} -- --static inline bool eth_addr_equal_except(const struct eth_addr a, -- const struct eth_addr b, -- const struct eth_addr mask) --{ -- return !(((a.be16[0] ^ b.be16[0]) & mask.be16[0]) -- || ((a.be16[1] ^ b.be16[1]) & mask.be16[1]) -- || ((a.be16[2] ^ b.be16[2]) & mask.be16[2])); --} -- --uint64_t eth_addr_to_uint64(const struct eth_addr ea); -- --static inline uint64_t eth_addr_vlan_to_uint64(const struct eth_addr ea, -- uint16_t vlan) --{ -- return (((uint64_t)vlan << 48) | eth_addr_to_uint64(ea)); --} -- --void eth_addr_from_uint64(uint64_t x, struct eth_addr *ea); -- --static inline struct eth_addr eth_addr_invert(const struct eth_addr src) --{ -- struct eth_addr dst; -- -- for (int i = 0; i < ARRAY_SIZE(src.be16); i++) { -- dst.be16[i] = ~src.be16[i]; -- } -- -- return dst; --} -- --void eth_addr_mark_random(struct eth_addr *ea); -- --static inline void eth_addr_random(struct eth_addr *ea) --{ -- random_bytes((uint8_t *)ea, sizeof *ea); -- eth_addr_mark_random(ea); --} -- --static inline void eth_addr_nicira_random(struct eth_addr *ea) --{ -- eth_addr_random(ea); -- -- /* Set the OUI to the Nicira one. */ -- ea->ea[0] = 0x00; -- ea->ea[1] = 0x23; -- ea->ea[2] = 0x20; -- -- /* Set the top bit to indicate random Nicira address. */ -- ea->ea[3] |= 0x80; --} --static inline uint32_t hash_mac(const struct eth_addr ea, -- const uint16_t vlan, const uint32_t basis) --{ -- return hash_uint64_basis(eth_addr_vlan_to_uint64(ea, vlan), basis); --} -- --bool eth_addr_is_reserved(const struct eth_addr); --bool eth_addr_from_string(const char *, struct eth_addr *); -- --void compose_rarp(struct dp_packet *, const struct eth_addr); -- --void eth_push_vlan(struct dp_packet *, ovs_be16 tpid, ovs_be16 tci); --void eth_pop_vlan(struct dp_packet *); -- --const char *eth_from_hex(const char *hex, struct dp_packet **packetp); --void eth_format_masked(const struct eth_addr ea, -- const struct eth_addr *mask, struct ds *s); -- --void set_mpls_lse(struct dp_packet *, ovs_be32 label); --void push_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse); --void pop_mpls(struct dp_packet *, ovs_be16 ethtype); -- --void set_mpls_lse_ttl(ovs_be32 *lse, uint8_t ttl); --void set_mpls_lse_tc(ovs_be32 *lse, uint8_t tc); --void set_mpls_lse_label(ovs_be32 *lse, ovs_be32 label); --void set_mpls_lse_bos(ovs_be32 *lse, uint8_t bos); --ovs_be32 set_mpls_lse_values(uint8_t ttl, uint8_t tc, uint8_t bos, -- ovs_be32 label); --void add_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse, -- bool l3_encap); -- --/* Example: -- * -- * struct eth_addr mac; -- * [...] -- * printf("The Ethernet address is "ETH_ADDR_FMT"\n", ETH_ADDR_ARGS(mac)); -- * -- */ --#define ETH_ADDR_FMT \ -- "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8 --#define ETH_ADDR_ARGS(EA) ETH_ADDR_BYTES_ARGS((EA).ea) --#define ETH_ADDR_BYTES_ARGS(EAB) \ -- (EAB)[0], (EAB)[1], (EAB)[2], (EAB)[3], (EAB)[4], (EAB)[5] --#define ETH_ADDR_STRLEN 17 -- --/* Example: -- * -- * struct eth_addr64 eui64; -- * [...] -- * printf("The EUI-64 address is "ETH_ADDR64_FMT"\n", ETH_ADDR64_ARGS(mac)); -- * -- */ --#define ETH_ADDR64_FMT \ -- "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":" \ -- "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8 --#define ETH_ADDR64_ARGS(EA) ETH_ADDR64_BYTES_ARGS((EA).ea64) --#define ETH_ADDR64_BYTES_ARGS(EAB) \ -- (EAB)[0], (EAB)[1], (EAB)[2], (EAB)[3], \ -- (EAB)[4], (EAB)[5], (EAB)[6], (EAB)[7] --#define ETH_ADDR64_STRLEN 23 -- --/* Example: -- * -- * char *string = "1 00:11:22:33:44:55 2"; -- * struct eth_addr mac; -- * int a, b; -- * -- * if (ovs_scan(string, "%d"ETH_ADDR_SCAN_FMT"%d", -- * &a, ETH_ADDR_SCAN_ARGS(mac), &b)) { -- * ... -- * } -- */ --#define ETH_ADDR_SCAN_FMT "%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8 --#define ETH_ADDR_SCAN_ARGS(EA) \ -- &(EA).ea[0], &(EA).ea[1], &(EA).ea[2], &(EA).ea[3], &(EA).ea[4], &(EA).ea[5] -- --#define ETH_TYPE_IP 0x0800 --#define ETH_TYPE_ARP 0x0806 --#define ETH_TYPE_TEB 0x6558 --#define ETH_TYPE_VLAN_8021Q 0x8100 --#define ETH_TYPE_VLAN ETH_TYPE_VLAN_8021Q --#define ETH_TYPE_VLAN_8021AD 0x88a8 --#define ETH_TYPE_IPV6 0x86dd --#define ETH_TYPE_LACP 0x8809 --#define ETH_TYPE_RARP 0x8035 --#define ETH_TYPE_MPLS 0x8847 --#define ETH_TYPE_MPLS_MCAST 0x8848 --#define ETH_TYPE_NSH 0x894f --#define ETH_TYPE_ERSPAN1 0x88be /* version 1 type II */ --#define ETH_TYPE_ERSPAN2 0x22eb /* version 2 type III */ -- --static inline bool eth_type_mpls(ovs_be16 eth_type) --{ -- return eth_type == htons(ETH_TYPE_MPLS) || -- eth_type == htons(ETH_TYPE_MPLS_MCAST); --} -- --static inline bool eth_type_vlan(ovs_be16 eth_type) --{ -- return eth_type == htons(ETH_TYPE_VLAN_8021Q) || -- eth_type == htons(ETH_TYPE_VLAN_8021AD); --} -- -- --/* Minimum value for an Ethernet type. Values below this are IEEE 802.2 frame -- * lengths. */ --#define ETH_TYPE_MIN 0x600 -- --#define ETH_HEADER_LEN 14 --#define ETH_PAYLOAD_MIN 46 --#define ETH_PAYLOAD_MAX 1500 --#define ETH_TOTAL_MIN (ETH_HEADER_LEN + ETH_PAYLOAD_MIN) --#define ETH_TOTAL_MAX (ETH_HEADER_LEN + ETH_PAYLOAD_MAX) --#define ETH_VLAN_TOTAL_MAX (ETH_HEADER_LEN + VLAN_HEADER_LEN + ETH_PAYLOAD_MAX) --struct eth_header { -- struct eth_addr eth_dst; -- struct eth_addr eth_src; -- ovs_be16 eth_type; --}; --BUILD_ASSERT_DECL(ETH_HEADER_LEN == sizeof(struct eth_header)); -- --void push_eth(struct dp_packet *packet, const struct eth_addr *dst, -- const struct eth_addr *src); --void pop_eth(struct dp_packet *packet); -- --void push_nsh(struct dp_packet *packet, const struct nsh_hdr *nsh_hdr_src); --bool pop_nsh(struct dp_packet *packet); -- --#define LLC_DSAP_SNAP 0xaa --#define LLC_SSAP_SNAP 0xaa --#define LLC_CNTL_SNAP 3 -- --#define LLC_HEADER_LEN 3 --struct llc_header { -- uint8_t llc_dsap; -- uint8_t llc_ssap; -- uint8_t llc_cntl; --}; --BUILD_ASSERT_DECL(LLC_HEADER_LEN == sizeof(struct llc_header)); -- --/* LLC field values used for STP frames. */ --#define STP_LLC_SSAP 0x42 --#define STP_LLC_DSAP 0x42 --#define STP_LLC_CNTL 0x03 -- --#define SNAP_ORG_ETHERNET "\0\0" /* The compiler adds a null byte, so -- sizeof(SNAP_ORG_ETHERNET) == 3. */ --#define SNAP_HEADER_LEN 5 --OVS_PACKED( --struct snap_header { -- uint8_t snap_org[3]; -- ovs_be16 snap_type; --}); --BUILD_ASSERT_DECL(SNAP_HEADER_LEN == sizeof(struct snap_header)); -- --#define LLC_SNAP_HEADER_LEN (LLC_HEADER_LEN + SNAP_HEADER_LEN) --OVS_PACKED( --struct llc_snap_header { -- struct llc_header llc; -- struct snap_header snap; --}); --BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); -- --#define VLAN_VID_MASK 0x0fff --#define VLAN_VID_SHIFT 0 -- --#define VLAN_PCP_MASK 0xe000 --#define VLAN_PCP_SHIFT 13 -- --#define VLAN_CFI 0x1000 --#define VLAN_CFI_SHIFT 12 -- --/* Given the vlan_tci field from an 802.1Q header, in network byte order, -- * returns the VLAN ID in host byte order. */ --static inline uint16_t --vlan_tci_to_vid(ovs_be16 vlan_tci) --{ -- return (ntohs(vlan_tci) & VLAN_VID_MASK) >> VLAN_VID_SHIFT; --} -- --/* Given the vlan_tci field from an 802.1Q header, in network byte order, -- * returns the priority code point (PCP) in host byte order. */ --static inline int --vlan_tci_to_pcp(ovs_be16 vlan_tci) --{ -- return (ntohs(vlan_tci) & VLAN_PCP_MASK) >> VLAN_PCP_SHIFT; --} -- --/* Given the vlan_tci field from an 802.1Q header, in network byte order, -- * returns the Canonical Format Indicator (CFI). */ --static inline int --vlan_tci_to_cfi(ovs_be16 vlan_tci) --{ -- return (vlan_tci & htons(VLAN_CFI)) != 0; --} -- --#define VLAN_HEADER_LEN 4 --struct vlan_header { -- ovs_be16 vlan_tci; /* Lowest 12 bits are VLAN ID. */ -- ovs_be16 vlan_next_type; --}; --BUILD_ASSERT_DECL(VLAN_HEADER_LEN == sizeof(struct vlan_header)); -- --#define VLAN_ETH_HEADER_LEN (ETH_HEADER_LEN + VLAN_HEADER_LEN) --struct vlan_eth_header { -- struct eth_addr veth_dst; -- struct eth_addr veth_src; -- ovs_be16 veth_type; /* Always htons(ETH_TYPE_VLAN). */ -- ovs_be16 veth_tci; /* Lowest 12 bits are VLAN ID. */ -- ovs_be16 veth_next_type; --}; --BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); -- --/* MPLS related definitions */ --#define MPLS_TTL_MASK 0x000000ff --#define MPLS_TTL_SHIFT 0 -- --#define MPLS_BOS_MASK 0x00000100 --#define MPLS_BOS_SHIFT 8 -- --#define MPLS_TC_MASK 0x00000e00 --#define MPLS_TC_SHIFT 9 -- --#define MPLS_LABEL_MASK 0xfffff000 --#define MPLS_LABEL_SHIFT 12 -- --#define MPLS_HLEN 4 -- --struct mpls_hdr { -- ovs_16aligned_be32 mpls_lse; --}; --BUILD_ASSERT_DECL(MPLS_HLEN == sizeof(struct mpls_hdr)); -- --/* Given a mpls label stack entry in network byte order -- * return mpls label in host byte order */ --static inline uint32_t --mpls_lse_to_label(ovs_be32 mpls_lse) --{ -- return (ntohl(mpls_lse) & MPLS_LABEL_MASK) >> MPLS_LABEL_SHIFT; --} -- --/* Given a mpls label stack entry in network byte order -- * return mpls tc */ --static inline uint8_t --mpls_lse_to_tc(ovs_be32 mpls_lse) --{ -- return (ntohl(mpls_lse) & MPLS_TC_MASK) >> MPLS_TC_SHIFT; --} -- --/* Given a mpls label stack entry in network byte order -- * return mpls ttl */ --static inline uint8_t --mpls_lse_to_ttl(ovs_be32 mpls_lse) --{ -- return (ntohl(mpls_lse) & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT; --} -- --/* Set label in mpls lse. */ --static inline void --flow_set_mpls_lse_label(ovs_be32 *mpls_lse, uint32_t label) --{ -- *mpls_lse &= ~htonl(MPLS_LABEL_MASK); -- *mpls_lse |= htonl(label << MPLS_LABEL_SHIFT); --} -- --/* Set TC in mpls lse. */ --static inline void --flow_set_mpls_lse_tc(ovs_be32 *mpls_lse, uint8_t tc) --{ -- *mpls_lse &= ~htonl(MPLS_TC_MASK); -- *mpls_lse |= htonl((tc & 0x7) << MPLS_TC_SHIFT); --} -- --/* Set BOS in mpls lse. */ --static inline void --flow_set_mpls_lse_bos(ovs_be32 *mpls_lse, uint8_t bos) --{ -- *mpls_lse &= ~htonl(MPLS_BOS_MASK); -- *mpls_lse |= htonl((bos & 0x1) << MPLS_BOS_SHIFT); --} -- --/* Set TTL in mpls lse. */ --static inline void --flow_set_mpls_lse_ttl(ovs_be32 *mpls_lse, uint8_t ttl) --{ -- *mpls_lse &= ~htonl(MPLS_TTL_MASK); -- *mpls_lse |= htonl(ttl << MPLS_TTL_SHIFT); --} -- --/* Given a mpls label stack entry in network byte order -- * return mpls BoS bit */ --static inline uint8_t --mpls_lse_to_bos(ovs_be32 mpls_lse) --{ -- return (mpls_lse & htonl(MPLS_BOS_MASK)) != 0; --} -- --#define IP_FMT "%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32 --#define IP_ARGS(ip) \ -- ntohl(ip) >> 24, \ -- (ntohl(ip) >> 16) & 0xff, \ -- (ntohl(ip) >> 8) & 0xff, \ -- ntohl(ip) & 0xff -- --/* Example: -- * -- * char *string = "1 33.44.55.66 2"; -- * ovs_be32 ip; -- * int a, b; -- * -- * if (ovs_scan(string, "%d"IP_SCAN_FMT"%d", &a, IP_SCAN_ARGS(&ip), &b)) { -- * ... -- * } -- */ --#define IP_SCAN_FMT "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8 --#define IP_SCAN_ARGS(ip) \ -- ((void) (ovs_be32) *(ip), &((uint8_t *) ip)[0]), \ -- &((uint8_t *) ip)[1], \ -- &((uint8_t *) ip)[2], \ -- &((uint8_t *) ip)[3] -- --#define IP_PORT_SCAN_FMT "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8":%"SCNu16 --#define IP_PORT_SCAN_ARGS(ip, port) \ -- ((void) (ovs_be32) *(ip), &((uint8_t *) ip)[0]), \ -- &((uint8_t *) ip)[1], \ -- &((uint8_t *) ip)[2], \ -- &((uint8_t *) ip)[3], \ -- ((void) (ovs_be16) *(port), (uint16_t *) port) -- --/* Returns true if 'netmask' is a CIDR netmask, that is, if it consists of N -- * high-order 1-bits and 32-N low-order 0-bits. */ --static inline bool --ip_is_cidr(ovs_be32 netmask) --{ -- uint32_t x = ~ntohl(netmask); -- return !(x & (x + 1)); --} --static inline bool --ip_is_multicast(ovs_be32 ip) --{ -- return (ip & htonl(0xf0000000)) == htonl(0xe0000000); --} --static inline bool --ip_is_local_multicast(ovs_be32 ip) --{ -- return (ip & htonl(0xffffff00)) == htonl(0xe0000000); --} --int ip_count_cidr_bits(ovs_be32 netmask); --void ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *); --bool ip_parse(const char *s, ovs_be32 *ip); --char *ip_parse_port(const char *s, ovs_be32 *ip, ovs_be16 *port) -- OVS_WARN_UNUSED_RESULT; --char *ip_parse_masked(const char *s, ovs_be32 *ip, ovs_be32 *mask) -- OVS_WARN_UNUSED_RESULT; --char *ip_parse_cidr(const char *s, ovs_be32 *ip, unsigned int *plen) -- OVS_WARN_UNUSED_RESULT; --char *ip_parse_masked_len(const char *s, int *n, ovs_be32 *ip, ovs_be32 *mask) -- OVS_WARN_UNUSED_RESULT; --char *ip_parse_cidr_len(const char *s, int *n, ovs_be32 *ip, -- unsigned int *plen) -- OVS_WARN_UNUSED_RESULT; -- --#define IP_VER(ip_ihl_ver) ((ip_ihl_ver) >> 4) --#define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15) --#define IP_IHL_VER(ihl, ver) (((ver) << 4) | (ihl)) -- --#ifndef IPPROTO_SCTP --#define IPPROTO_SCTP 132 --#endif -- --#ifndef IPPROTO_DCCP --#define IPPROTO_DCCP 33 --#endif -- --#ifndef IPPROTO_IGMP --#define IPPROTO_IGMP 2 --#endif -- --#ifndef IPPROTO_UDPLITE --#define IPPROTO_UDPLITE 136 --#endif -- --/* TOS fields. */ --#define IP_ECN_NOT_ECT 0x0 --#define IP_ECN_ECT_1 0x01 --#define IP_ECN_ECT_0 0x02 --#define IP_ECN_CE 0x03 --#define IP_ECN_MASK 0x03 --#define IP_DSCP_CS6 0xc0 --#define IP_DSCP_MASK 0xfc -- --static inline int --IP_ECN_is_ce(uint8_t dsfield) --{ -- return (dsfield & IP_ECN_MASK) == IP_ECN_CE; --} -- --#define IP_VERSION 4 -- --#define IP_DONT_FRAGMENT 0x4000 /* Don't fragment. */ --#define IP_MORE_FRAGMENTS 0x2000 /* More fragments. */ --#define IP_FRAG_OFF_MASK 0x1fff /* Fragment offset. */ --#define IP_IS_FRAGMENT(ip_frag_off) \ -- ((ip_frag_off) & htons(IP_MORE_FRAGMENTS | IP_FRAG_OFF_MASK)) -- --#define IP_HEADER_LEN 20 --struct ip_header { -- uint8_t ip_ihl_ver; -- uint8_t ip_tos; -- ovs_be16 ip_tot_len; -- ovs_be16 ip_id; -- ovs_be16 ip_frag_off; -- uint8_t ip_ttl; -- uint8_t ip_proto; -- ovs_be16 ip_csum; -- ovs_16aligned_be32 ip_src; -- ovs_16aligned_be32 ip_dst; --}; --BUILD_ASSERT_DECL(IP_HEADER_LEN == sizeof(struct ip_header)); -- --/* ICMPv4 types. */ --#define ICMP4_ECHO_REPLY 0 --#define ICMP4_DST_UNREACH 3 --#define ICMP4_SOURCEQUENCH 4 --#define ICMP4_REDIRECT 5 --#define ICMP4_ECHO_REQUEST 8 --#define ICMP4_TIME_EXCEEDED 11 --#define ICMP4_PARAM_PROB 12 --#define ICMP4_TIMESTAMP 13 --#define ICMP4_TIMESTAMPREPLY 14 --#define ICMP4_INFOREQUEST 15 --#define ICMP4_INFOREPLY 16 -- --#define ICMP_HEADER_LEN 8 --struct icmp_header { -- uint8_t icmp_type; -- uint8_t icmp_code; -- ovs_be16 icmp_csum; -- union { -- struct { -- ovs_be16 id; -- ovs_be16 seq; -- } echo; -- struct { -- ovs_be16 empty; -- ovs_be16 mtu; -- } frag; -- ovs_16aligned_be32 gateway; -- } icmp_fields; --}; --BUILD_ASSERT_DECL(ICMP_HEADER_LEN == sizeof(struct icmp_header)); -- --/* ICMPV4 */ --#define ICMP_ERROR_DATA_L4_LEN 8 -- --#define IGMP_HEADER_LEN 8 --struct igmp_header { -- uint8_t igmp_type; -- uint8_t igmp_code; -- ovs_be16 igmp_csum; -- ovs_16aligned_be32 group; --}; --BUILD_ASSERT_DECL(IGMP_HEADER_LEN == sizeof(struct igmp_header)); -- --#define IGMPV3_HEADER_LEN 8 --struct igmpv3_header { -- uint8_t type; -- uint8_t rsvr1; -- ovs_be16 csum; -- ovs_be16 rsvr2; -- ovs_be16 ngrp; --}; --BUILD_ASSERT_DECL(IGMPV3_HEADER_LEN == sizeof(struct igmpv3_header)); -- --#define IGMPV3_QUERY_HEADER_LEN 12 --struct igmpv3_query_header { -- uint8_t type; -- uint8_t max_resp; -- ovs_be16 csum; -- ovs_16aligned_be32 group; -- uint8_t srs_qrv; -- uint8_t qqic; -- ovs_be16 nsrcs; --}; --BUILD_ASSERT_DECL( -- IGMPV3_QUERY_HEADER_LEN == sizeof(struct igmpv3_query_header --)); -- --#define IGMPV3_RECORD_LEN 8 --struct igmpv3_record { -- uint8_t type; -- uint8_t aux_len; -- ovs_be16 nsrcs; -- ovs_16aligned_be32 maddr; --}; --BUILD_ASSERT_DECL(IGMPV3_RECORD_LEN == sizeof(struct igmpv3_record)); -- --#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */ --#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */ --#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x12 */ --#define IGMP_HOST_LEAVE_MESSAGE 0x17 --#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x12 */ -- --/* -- * IGMPv3 and MLDv2 use the same codes. -- */ --#define IGMPV3_MODE_IS_INCLUDE 1 --#define IGMPV3_MODE_IS_EXCLUDE 2 --#define IGMPV3_CHANGE_TO_INCLUDE_MODE 3 --#define IGMPV3_CHANGE_TO_EXCLUDE_MODE 4 --#define IGMPV3_ALLOW_NEW_SOURCES 5 --#define IGMPV3_BLOCK_OLD_SOURCES 6 -- --#define SCTP_HEADER_LEN 12 --struct sctp_header { -- ovs_be16 sctp_src; -- ovs_be16 sctp_dst; -- ovs_16aligned_be32 sctp_vtag; -- ovs_16aligned_be32 sctp_csum; --}; --BUILD_ASSERT_DECL(SCTP_HEADER_LEN == sizeof(struct sctp_header)); -- --#define UDP_HEADER_LEN 8 --struct udp_header { -- ovs_be16 udp_src; -- ovs_be16 udp_dst; -- ovs_be16 udp_len; -- ovs_be16 udp_csum; --}; --BUILD_ASSERT_DECL(UDP_HEADER_LEN == sizeof(struct udp_header)); -- --#define ESP_HEADER_LEN 8 --struct esp_header { -- ovs_be32 spi; -- ovs_be32 seq_no; --}; --BUILD_ASSERT_DECL(ESP_HEADER_LEN == sizeof(struct esp_header)); -- --#define ESP_TRAILER_LEN 2 --struct esp_trailer { -- uint8_t pad_len; -- uint8_t next_hdr; --}; --BUILD_ASSERT_DECL(ESP_TRAILER_LEN == sizeof(struct esp_trailer)); -- --#define TCP_FIN 0x001 --#define TCP_SYN 0x002 --#define TCP_RST 0x004 --#define TCP_PSH 0x008 --#define TCP_ACK 0x010 --#define TCP_URG 0x020 --#define TCP_ECE 0x040 --#define TCP_CWR 0x080 --#define TCP_NS 0x100 -- --#define TCP_CTL(flags, offset) (htons((flags) | ((offset) << 12))) --#define TCP_FLAGS(tcp_ctl) (ntohs(tcp_ctl) & 0x0fff) --#define TCP_FLAGS_BE16(tcp_ctl) ((tcp_ctl) & htons(0x0fff)) --#define TCP_OFFSET(tcp_ctl) (ntohs(tcp_ctl) >> 12) -- --#define TCP_HEADER_LEN 20 --struct tcp_header { -- ovs_be16 tcp_src; -- ovs_be16 tcp_dst; -- ovs_16aligned_be32 tcp_seq; -- ovs_16aligned_be32 tcp_ack; -- ovs_be16 tcp_ctl; -- ovs_be16 tcp_winsz; -- ovs_be16 tcp_csum; -- ovs_be16 tcp_urg; --}; --BUILD_ASSERT_DECL(TCP_HEADER_LEN == sizeof(struct tcp_header)); -- --/* Connection states. -- * -- * Names like CS_RELATED are bit values, e.g. 1 << 2. -- * Names like CS_RELATED_BIT are bit indexes, e.g. 2. */ --#define CS_STATES \ -- CS_STATE(NEW, 0, "new") \ -- CS_STATE(ESTABLISHED, 1, "est") \ -- CS_STATE(RELATED, 2, "rel") \ -- CS_STATE(REPLY_DIR, 3, "rpl") \ -- CS_STATE(INVALID, 4, "inv") \ -- CS_STATE(TRACKED, 5, "trk") \ -- CS_STATE(SRC_NAT, 6, "snat") \ -- CS_STATE(DST_NAT, 7, "dnat") -- --enum { --#define CS_STATE(ENUM, INDEX, NAME) \ -- CS_##ENUM = 1 << INDEX, \ -- CS_##ENUM##_BIT = INDEX, -- CS_STATES --#undef CS_STATE --}; -- --/* Undefined connection state bits. */ --enum { --#define CS_STATE(ENUM, INDEX, NAME) +CS_##ENUM -- CS_SUPPORTED_MASK = CS_STATES --#undef CS_STATE --}; --#define CS_UNSUPPORTED_MASK (~(uint32_t)CS_SUPPORTED_MASK) -- --#define ARP_HRD_ETHERNET 1 --#define ARP_PRO_IP 0x0800 --#define ARP_OP_REQUEST 1 --#define ARP_OP_REPLY 2 --#define ARP_OP_RARP 3 -- --#define ARP_ETH_HEADER_LEN 28 --struct arp_eth_header { -- /* Generic members. */ -- ovs_be16 ar_hrd; /* Hardware type. */ -- ovs_be16 ar_pro; /* Protocol type. */ -- uint8_t ar_hln; /* Hardware address length. */ -- uint8_t ar_pln; /* Protocol address length. */ -- ovs_be16 ar_op; /* Opcode. */ -- -- /* Ethernet+IPv4 specific members. */ -- struct eth_addr ar_sha; /* Sender hardware address. */ -- ovs_16aligned_be32 ar_spa; /* Sender protocol address. */ -- struct eth_addr ar_tha; /* Target hardware address. */ -- ovs_16aligned_be32 ar_tpa; /* Target protocol address. */ --}; --BUILD_ASSERT_DECL(ARP_ETH_HEADER_LEN == sizeof(struct arp_eth_header)); -- --#define IPV6_HEADER_LEN 40 -- --/* Like struct in6_addr, but whereas that struct requires 32-bit alignment on -- * most implementations, this one only requires 16-bit alignment. */ --union ovs_16aligned_in6_addr { -- ovs_be16 be16[8]; -- ovs_16aligned_be32 be32[4]; --}; -- --/* Like struct ip6_hdr, but whereas that struct requires 32-bit alignment, this -- * one only requires 16-bit alignment. */ --struct ovs_16aligned_ip6_hdr { -- union { -- struct ovs_16aligned_ip6_hdrctl { -- ovs_16aligned_be32 ip6_un1_flow; -- ovs_be16 ip6_un1_plen; -- uint8_t ip6_un1_nxt; -- uint8_t ip6_un1_hlim; -- } ip6_un1; -- uint8_t ip6_un2_vfc; -- } ip6_ctlun; -- union ovs_16aligned_in6_addr ip6_src; -- union ovs_16aligned_in6_addr ip6_dst; --}; -- --/* Like struct in6_frag, but whereas that struct requires 32-bit alignment, -- * this one only requires 16-bit alignment. */ --struct ovs_16aligned_ip6_frag { -- uint8_t ip6f_nxt; -- uint8_t ip6f_reserved; -- ovs_be16 ip6f_offlg; -- ovs_16aligned_be32 ip6f_ident; --}; -- --#define ICMP6_HEADER_LEN 4 --struct icmp6_header { -- uint8_t icmp6_type; -- uint8_t icmp6_code; -- ovs_be16 icmp6_cksum; --}; --BUILD_ASSERT_DECL(ICMP6_HEADER_LEN == sizeof(struct icmp6_header)); -- --#define ICMP6_DATA_HEADER_LEN 8 --struct icmp6_data_header { -- struct icmp6_header icmp6_base; -- union { -- ovs_16aligned_be32 be32[1]; -- ovs_be16 be16[2]; -- uint8_t u8[4]; -- } icmp6_data; --}; --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 *, -- const void *, uint8_t, uint16_t); -- --/* Neighbor Discovery option field. -- * ND options are always a multiple of 8 bytes in size. */ --#define ND_LLA_OPT_LEN 8 --struct ovs_nd_lla_opt { -- uint8_t type; /* One of ND_OPT_*_LINKADDR. */ -- uint8_t len; -- struct eth_addr mac; --}; --BUILD_ASSERT_DECL(ND_LLA_OPT_LEN == sizeof(struct ovs_nd_lla_opt)); -- --/* Neighbor Discovery option: Prefix Information. */ --#define ND_PREFIX_OPT_LEN 32 --struct ovs_nd_prefix_opt { -- uint8_t type; /* ND_OPT_PREFIX_INFORMATION. */ -- uint8_t len; /* Always 4. */ -- uint8_t prefix_len; -- uint8_t la_flags; /* ND_PREFIX_* flags. */ -- ovs_16aligned_be32 valid_lifetime; -- ovs_16aligned_be32 preferred_lifetime; -- ovs_16aligned_be32 reserved; /* Always 0. */ -- union ovs_16aligned_in6_addr prefix; --}; --BUILD_ASSERT_DECL(ND_PREFIX_OPT_LEN == sizeof(struct ovs_nd_prefix_opt)); -- --/* Neighbor Discovery option: MTU. */ --#define ND_MTU_OPT_LEN 8 --#define ND_MTU_DEFAULT 0 --struct ovs_nd_mtu_opt { -- uint8_t type; /* ND_OPT_MTU */ -- uint8_t len; /* Always 1. */ -- ovs_be16 reserved; /* Always 0. */ -- ovs_16aligned_be32 mtu; --}; --BUILD_ASSERT_DECL(ND_MTU_OPT_LEN == sizeof(struct ovs_nd_mtu_opt)); -- --/* Like struct nd_msg (from ndisc.h), but whereas that struct requires 32-bit -- * alignment, this one only requires 16-bit alignment. */ --#define ND_MSG_LEN 24 --struct ovs_nd_msg { -- struct icmp6_header icmph; -- ovs_16aligned_be32 rso_flags; -- union ovs_16aligned_in6_addr target; -- struct ovs_nd_lla_opt options[0]; --}; --BUILD_ASSERT_DECL(ND_MSG_LEN == sizeof(struct ovs_nd_msg)); -- --/* Neighbor Discovery packet flags. */ --#define ND_RSO_ROUTER 0x80000000 --#define ND_RSO_SOLICITED 0x40000000 --#define ND_RSO_OVERRIDE 0x20000000 -- --#define RA_MSG_LEN 16 --struct ovs_ra_msg { -- struct icmp6_header icmph; -- uint8_t cur_hop_limit; -- uint8_t mo_flags; /* ND_RA_MANAGED_ADDRESS and ND_RA_OTHER_CONFIG flags. */ -- ovs_be16 router_lifetime; -- ovs_be32 reachable_time; -- ovs_be32 retrans_timer; -- struct ovs_nd_lla_opt options[0]; --}; --BUILD_ASSERT_DECL(RA_MSG_LEN == sizeof(struct ovs_ra_msg)); -- --#define ND_RA_MANAGED_ADDRESS 0x80 --#define ND_RA_OTHER_CONFIG 0x40 -- --/* Defaults based on MaxRtrInterval and MinRtrInterval from RFC 4861 section -- * 6.2.1 -- */ --#define ND_RA_MAX_INTERVAL_DEFAULT 600 -- --static inline int --nd_ra_min_interval_default(int max) --{ -- return max >= 9 ? max / 3 : max * 3 / 4; --} -- --/* -- * Use the same struct for MLD and MLD2, naming members as the defined fields in -- * in the corresponding version of the protocol, though they are reserved in the -- * other one. -- */ --#define MLD_HEADER_LEN 8 --struct mld_header { -- uint8_t type; -- uint8_t code; -- ovs_be16 csum; -- ovs_be16 mrd; -- ovs_be16 ngrp; --}; --BUILD_ASSERT_DECL(MLD_HEADER_LEN == sizeof(struct mld_header)); -- --#define MLD2_RECORD_LEN 20 --struct mld2_record { -- uint8_t type; -- uint8_t aux_len; -- ovs_be16 nsrcs; -- union ovs_16aligned_in6_addr maddr; --}; --BUILD_ASSERT_DECL(MLD2_RECORD_LEN == sizeof(struct mld2_record)); -- --#define MLD_QUERY 130 --#define MLD_REPORT 131 --#define MLD_DONE 132 --#define MLD2_REPORT 143 -- --/* The IPv6 flow label is in the lower 20 bits of the first 32-bit word. */ --#define IPV6_LABEL_MASK 0x000fffff -- --/* Example: -- * -- * char *string = "1 ::1 2"; -- * char ipv6_s[IPV6_SCAN_LEN + 1]; -- * struct in6_addr ipv6; -- * -- * if (ovs_scan(string, "%d"IPV6_SCAN_FMT"%d", &a, ipv6_s, &b) -- * && inet_pton(AF_INET6, ipv6_s, &ipv6) == 1) { -- * ... -- * } -- */ --#define IPV6_SCAN_FMT "%46[0123456789abcdefABCDEF:.]" --#define IPV6_SCAN_LEN 46 -- --extern const struct in6_addr in6addr_exact; --#define IN6ADDR_EXACT_INIT { { { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \ -- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } } } -- --extern const struct in6_addr in6addr_all_hosts; --#define IN6ADDR_ALL_HOSTS_INIT { { { 0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, \ -- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 } } } -- --extern const struct in6_addr in6addr_all_routers; --#define IN6ADDR_ALL_ROUTERS_INIT { { { 0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, \ -- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 } } } -- --static inline bool ipv6_addr_equals(const struct in6_addr *a, -- const struct in6_addr *b) --{ --#ifdef IN6_ARE_ADDR_EQUAL -- return IN6_ARE_ADDR_EQUAL(a, b); --#else -- return !memcmp(a, b, sizeof(*a)); --#endif --} -- --/* Checks the IPv6 address in 'mask' for all zeroes. */ --static inline bool ipv6_mask_is_any(const struct in6_addr *mask) { -- return ipv6_addr_equals(mask, &in6addr_any); --} -- --static inline bool ipv6_mask_is_exact(const struct in6_addr *mask) { -- return ipv6_addr_equals(mask, &in6addr_exact); --} -- --static inline bool ipv6_is_all_hosts(const struct in6_addr *addr) { -- return ipv6_addr_equals(addr, &in6addr_all_hosts); --} -- --static inline bool ipv6_addr_is_set(const struct in6_addr *addr) { -- return !ipv6_addr_equals(addr, &in6addr_any); --} -- --static inline bool ipv6_addr_is_multicast(const struct in6_addr *ip) { -- return ip->s6_addr[0] == 0xff; --} -- --static inline struct in6_addr --in6_addr_mapped_ipv4(ovs_be32 ip4) --{ -- struct in6_addr ip6; -- memset(&ip6, 0, sizeof(ip6)); -- ip6.s6_addr[10] = 0xff, ip6.s6_addr[11] = 0xff; -- memcpy(&ip6.s6_addr[12], &ip4, 4); -- return ip6; --} -- --static inline void --in6_addr_set_mapped_ipv4(struct in6_addr *ip6, ovs_be32 ip4) --{ -- *ip6 = in6_addr_mapped_ipv4(ip4); --} -- --static inline ovs_be32 --in6_addr_get_mapped_ipv4(const struct in6_addr *addr) --{ -- union ovs_16aligned_in6_addr *taddr = -- (union ovs_16aligned_in6_addr *) addr; -- if (IN6_IS_ADDR_V4MAPPED(addr)) { -- return get_16aligned_be32(&taddr->be32[3]); -- } else { -- return INADDR_ANY; -- } --} -- --void in6_addr_solicited_node(struct in6_addr *addr, -- const struct in6_addr *ip6); -- --void in6_generate_eui64(struct eth_addr ea, const struct in6_addr *prefix, -- struct in6_addr *lla); -- --void in6_generate_lla(struct eth_addr ea, struct in6_addr *lla); -- --/* Returns true if 'addr' is a link local address. Otherwise, false. */ --bool in6_is_lla(struct in6_addr *addr); -- --void ipv6_multicast_to_ethernet(struct eth_addr *eth, -- const struct in6_addr *ip6); -- --static inline bool dl_type_is_ip_any(ovs_be16 dl_type) --{ -- return dl_type == htons(ETH_TYPE_IP) -- || dl_type == htons(ETH_TYPE_IPV6); --} -- --/* Tunnel header */ -- --/* GRE protocol header */ --struct gre_base_hdr { -- ovs_be16 flags; -- ovs_be16 protocol; --}; -- --#define GRE_CSUM 0x8000 --#define GRE_ROUTING 0x4000 --#define GRE_KEY 0x2000 --#define GRE_SEQ 0x1000 --#define GRE_STRICT 0x0800 --#define GRE_REC 0x0700 --#define GRE_FLAGS 0x00F8 --#define GRE_VERSION 0x0007 -- --/* -- * ERSPAN protocol header and metadata -- * -- * Version 1 (Type II) header (8 octets [42:49]) -- * 0 1 2 3 -- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | Ver | VLAN | COS | En|T| Session ID | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | Reserved | Index | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * -- * -- * ERSPAN Version 2 (Type III) header (12 octets [42:49]) -- * 0 1 2 3 -- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | Ver | VLAN | COS |BSO|T| Session ID | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | Timestamp | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | SGT |P| FT | Hw ID |D|Gra|O| -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * -- */ -- --/* ERSPAN has fixed 8-byte GRE header */ --#define ERSPAN_GREHDR_LEN 8 --#define ERSPAN_HDR(gre_base_hdr) \ -- ((struct erspan_base_hdr *)((char *)gre_base_hdr + ERSPAN_GREHDR_LEN)) -- --#define ERSPAN_V1_MDSIZE 4 --#define ERSPAN_V2_MDSIZE 8 -- --#define ERSPAN_SID_MASK 0x03ff /* 10-bit Session ID. */ --#define ERSPAN_IDX_MASK 0xfffff /* v1 Index */ --#define ERSPAN_HWID_MASK 0x03f0 --#define ERSPAN_DIR_MASK 0x0008 -- --struct erspan_base_hdr { --#ifdef WORDS_BIGENDIAN -- uint8_t ver:4, -- vlan_upper:4; -- uint8_t vlan:8; -- uint8_t cos:3, -- en:2, -- t:1, -- session_id_upper:2; -- uint8_t session_id:8; --#else -- uint8_t vlan_upper:4, -- ver:4; -- uint8_t vlan:8; -- uint8_t session_id_upper:2, -- t:1, -- en:2, -- cos:3; -- uint8_t session_id:8; --#endif --}; -- --struct erspan_md2 { -- ovs_16aligned_be32 timestamp; -- ovs_be16 sgt; --#ifdef WORDS_BIGENDIAN -- uint8_t p:1, -- ft:5, -- hwid_upper:2; -- uint8_t hwid:4, -- dir:1, -- gra:2, -- o:1; --#else -- uint8_t hwid_upper:2, -- ft:5, -- p:1; -- uint8_t o:1, -- gra:2, -- dir:1, -- hwid:4; --#endif --}; -- --struct erspan_metadata { -- int version; -- union { -- ovs_be32 index; /* Version 1 (type II)*/ -- struct erspan_md2 md2; /* Version 2 (type III) */ -- } u; --}; -- --static inline uint16_t get_sid(const struct erspan_base_hdr *ershdr) --{ -- return (ershdr->session_id_upper << 8) + ershdr->session_id; --} -- --static inline void set_sid(struct erspan_base_hdr *ershdr, uint16_t id) --{ -- ershdr->session_id = id & 0xff; -- ershdr->session_id_upper = (id >> 8) &0x3; --} -- --static inline uint8_t get_hwid(const struct erspan_md2 *md2) --{ -- return (md2->hwid_upper << 4) + md2->hwid; --} -- --static inline void set_hwid(struct erspan_md2 *md2, uint8_t hwid) --{ -- md2->hwid = hwid & 0xf; -- md2->hwid_upper = (hwid >> 4) & 0x3; --} -- --/* ERSPAN timestamp granularity -- * 00b --> granularity = 100 microseconds -- * 01b --> granularity = 100 nanoseconds -- * 10b --> granularity = IEEE 1588 -- * Here we only support 100 microseconds. -- */ --enum erspan_ts_gra { -- ERSPAN_100US, -- ERSPAN_100NS, -- ERSPAN_IEEE1588, --}; -- --static inline ovs_be32 get_erspan_ts(enum erspan_ts_gra gra) --{ -- ovs_be32 ts = 0; -- -- switch (gra) { -- case ERSPAN_100US: -- ts = htonl((uint32_t)(time_wall_usec() / 100)); -- break; -- case ERSPAN_100NS: -- /* fall back */ -- case ERSPAN_IEEE1588: -- /* fall back */ -- default: -- OVS_NOT_REACHED(); -- break; -- } -- return ts; --} -- --/* -- * GTP-U protocol header and metadata -- * See: -- * User Plane Protocol and Architectural Analysis on 3GPP 5G System -- * draft-hmm-dmm-5g-uplane-analysis-00 -- * -- * 0 1 2 3 -- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | Ver |P|R|E|S|N| Message Type| Length | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | Tunnel Endpoint Identifier | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | Sequence Number | N-PDU Number | Next-Ext-Hdr | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * -- * GTP-U Flags: -- * P: Protocol Type (Set to '1') -- * R: Reserved Bit (Set to '0') -- * E: Extension Header Flag (Set to '1' if extension header exists) -- * S: Sequence Number Flag (Set to '1' if sequence number exists) -- * N: N-PDU Number Flag (Set to '1' if N-PDU number exists) -- * -- * GTP-U Message Type: -- * Indicates the type of GTP-U message. -- * -- * GTP-U Length: -- * Indicates the length in octets of the payload. -- * -- * User payload is transmitted in G-PDU packets. -- */ -- --#define GTPU_VER_MASK 0xe0 --#define GTPU_P_MASK 0x10 --#define GTPU_E_MASK 0x04 --#define GTPU_S_MASK 0x02 -- --/* GTP-U UDP port. */ --#define GTPU_DST_PORT 2152 -- --/* Default GTP-U flags: Ver = 1 and P = 1. */ --#define GTPU_FLAGS_DEFAULT 0x30 -- --/* GTP-U message type for normal user plane PDU. */ --#define GTPU_MSGTYPE_REQ 1 /* Echo Request. */ --#define GTPU_MSGTYPE_REPL 2 /* Echo Reply. */ --#define GTPU_MSGTYPE_GPDU 255 /* User Payload. */ -- --struct gtpu_metadata { -- uint8_t flags; -- uint8_t msgtype; --}; --BUILD_ASSERT_DECL(sizeof(struct gtpu_metadata) == 2); -- --struct gtpuhdr { -- struct gtpu_metadata md; -- ovs_be16 len; -- ovs_16aligned_be32 teid; --}; --BUILD_ASSERT_DECL(sizeof(struct gtpuhdr) == 8); -- --struct gtpuhdr_opt { -- ovs_be16 seqno; -- uint8_t pdu_number; -- uint8_t next_ext_type; --}; --BUILD_ASSERT_DECL(sizeof(struct gtpuhdr_opt) == 4); -- --/* VXLAN protocol header */ --struct vxlanhdr { -- union { -- ovs_16aligned_be32 vx_flags; /* VXLAN flags. */ -- struct { -- uint8_t flags; /* VXLAN GPE flags. */ -- uint8_t reserved[2]; /* 16 bits reserved. */ -- uint8_t next_protocol; /* Next Protocol field for VXLAN GPE. */ -- } vx_gpe; -- }; -- ovs_16aligned_be32 vx_vni; --}; --BUILD_ASSERT_DECL(sizeof(struct vxlanhdr) == 8); -- --#define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ -- --/* -- * VXLAN Generic Protocol Extension (VXLAN_F_GPE): -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * |R|R|Ver|I|P|R|O| Reserved |Next Protocol | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * | VXLAN Network Identifier (VNI) | Reserved | -- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- * -- * Ver = Version. Indicates VXLAN GPE protocol version. -- * -- * P = Next Protocol Bit. The P bit is set to indicate that the -- * Next Protocol field is present. -- * -- * O = OAM Flag Bit. The O bit is set to indicate that the packet -- * is an OAM packet. -- * -- * Next Protocol = This 8 bit field indicates the protocol header -- * immediately following the VXLAN GPE header. -- * -- * https://tools.ietf.org/html/draft-ietf-nvo3-vxlan-gpe-01 -- */ -- --/* Fields in struct vxlanhdr.vx_gpe.flags */ --#define VXLAN_GPE_FLAGS_VER 0x30 /* Version. */ --#define VXLAN_GPE_FLAGS_P 0x04 /* Next Protocol Bit. */ --#define VXLAN_GPE_FLAGS_O 0x01 /* OAM Bit. */ -- --/* VXLAN-GPE header flags. */ --#define VXLAN_HF_VER ((1U <<29) | (1U <<28)) --#define VXLAN_HF_NP (1U <<26) --#define VXLAN_HF_OAM (1U <<24) -- --#define VXLAN_GPE_USED_BITS (VXLAN_HF_VER | VXLAN_HF_NP | VXLAN_HF_OAM | \ -- 0xff) -- --/* VXLAN-GPE header Next Protocol. */ --#define VXLAN_GPE_NP_IPV4 0x01 --#define VXLAN_GPE_NP_IPV6 0x02 --#define VXLAN_GPE_NP_ETHERNET 0x03 --#define VXLAN_GPE_NP_NSH 0x04 -- --#define VXLAN_F_GPE 0x4000 --#define VXLAN_HF_GPE 0x04000000 -- --/* Input values for PACKET_TYPE macros have to be in host byte order. -- * The _BE postfix indicates result is in network byte order. Otherwise result -- * is in host byte order. */ --#define PACKET_TYPE(NS, NS_TYPE) ((uint32_t) ((NS) << 16 | (NS_TYPE))) --#define PACKET_TYPE_BE(NS, NS_TYPE) (htonl((NS) << 16 | (NS_TYPE))) -- --/* Returns the host byte ordered namespace of 'packet type'. */ --static inline uint16_t --pt_ns(ovs_be32 packet_type) --{ -- return ntohl(packet_type) >> 16; --} -- --/* Returns the network byte ordered namespace type of 'packet type'. */ --static inline ovs_be16 --pt_ns_type_be(ovs_be32 packet_type) --{ -- return be32_to_be16(packet_type); --} -- --/* Returns the host byte ordered namespace type of 'packet type'. */ --static inline uint16_t --pt_ns_type(ovs_be32 packet_type) --{ -- return ntohs(pt_ns_type_be(packet_type)); --} -- --/* Well-known packet_type field values. */ --enum packet_type { -- PT_ETH = PACKET_TYPE(OFPHTN_ONF, 0x0000), /* Default PT: Ethernet */ -- PT_USE_NEXT_PROTO = PACKET_TYPE(OFPHTN_ONF, 0xfffe), /* Pseudo PT for decap. */ -- PT_IPV4 = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_IP), -- PT_IPV6 = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_IPV6), -- PT_MPLS = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_MPLS), -- PT_MPLS_MC = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_MPLS_MCAST), -- PT_NSH = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_NSH), -- PT_UNKNOWN = PACKET_TYPE(0xffff, 0xffff), /* Unknown packet type. */ --}; -- -- --void ipv6_format_addr(const struct in6_addr *addr, struct ds *); --void ipv6_format_addr_bracket(const struct in6_addr *addr, struct ds *, -- bool bracket); --void ipv6_format_mapped(const struct in6_addr *addr, struct ds *); --void ipv6_format_masked(const struct in6_addr *addr, -- const struct in6_addr *mask, struct ds *); --const char * ipv6_string_mapped(char *addr_str, const struct in6_addr *addr); --struct in6_addr ipv6_addr_bitand(const struct in6_addr *src, -- const struct in6_addr *mask); --struct in6_addr ipv6_addr_bitxor(const struct in6_addr *a, -- const struct in6_addr *b); --bool ipv6_is_zero(const struct in6_addr *a); --struct in6_addr ipv6_create_mask(int mask); --int ipv6_count_cidr_bits(const struct in6_addr *netmask); --bool ipv6_is_cidr(const struct in6_addr *netmask); -- --bool ipv6_parse(const char *s, struct in6_addr *ip); --char *ipv6_parse_masked(const char *s, struct in6_addr *ipv6, -- struct in6_addr *mask); --char *ipv6_parse_cidr(const char *s, struct in6_addr *ip, unsigned int *plen) -- OVS_WARN_UNUSED_RESULT; --char *ipv6_parse_masked_len(const char *s, int *n, struct in6_addr *ipv6, -- struct in6_addr *mask); --char *ipv6_parse_cidr_len(const char *s, int *n, struct in6_addr *ip, -- unsigned int *plen) -- OVS_WARN_UNUSED_RESULT; -- --void *eth_compose(struct dp_packet *, const struct eth_addr eth_dst, -- const struct eth_addr eth_src, uint16_t eth_type, -- size_t size); --void *snap_compose(struct dp_packet *, const struct eth_addr eth_dst, -- const struct eth_addr eth_src, -- unsigned int oui, uint16_t snap_type, size_t size); --void packet_set_ipv4(struct dp_packet *, ovs_be32 src, ovs_be32 dst, uint8_t tos, -- uint8_t ttl); --void packet_set_ipv4_addr(struct dp_packet *packet, ovs_16aligned_be32 *addr, -- ovs_be32 new_addr); --void packet_set_ipv6(struct dp_packet *, const struct in6_addr *src, -- const struct in6_addr *dst, uint8_t tc, -- ovs_be32 fl, uint8_t hlmit); --void packet_set_ipv6_addr(struct dp_packet *packet, uint8_t proto, -- ovs_16aligned_be32 addr[4], -- const struct in6_addr *new_addr, -- bool recalculate_csum); --void packet_set_tcp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst); --void packet_set_udp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst); --void packet_set_sctp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst); --void packet_set_icmp(struct dp_packet *, uint8_t type, uint8_t code); --void packet_set_nd(struct dp_packet *, const struct in6_addr *target, -- const struct eth_addr sll, const struct eth_addr tll); --void packet_set_nd_ext(struct dp_packet *packet, -- const ovs_16aligned_be32 rso_flags, -- const uint8_t opt_type); --void packet_set_igmp3_query(struct dp_packet *, uint8_t max_resp, -- ovs_be32 group, bool srs, uint8_t qrv, -- uint8_t qqic); --void packet_format_tcp_flags(struct ds *, uint16_t); --const char *packet_tcp_flag_to_string(uint32_t flag); --void *compose_ipv6(struct dp_packet *packet, uint8_t proto, -- const struct in6_addr *src, const struct in6_addr *dst, -- uint8_t key_tc, ovs_be32 key_fl, uint8_t key_hl, int size); --void compose_arp__(struct dp_packet *); --void compose_arp(struct dp_packet *, uint16_t arp_op, -- const struct eth_addr arp_sha, -- const struct eth_addr arp_tha, bool broadcast, -- ovs_be32 arp_spa, ovs_be32 arp_tpa); --void compose_nd_ns(struct dp_packet *, const struct eth_addr eth_src, -- const struct in6_addr *ipv6_src, -- const struct in6_addr *ipv6_dst); --void compose_nd_na(struct dp_packet *, const struct eth_addr eth_src, -- const struct eth_addr eth_dst, -- const struct in6_addr *ipv6_src, -- const struct in6_addr *ipv6_dst, -- ovs_be32 rso_flags); --void compose_nd_ra(struct dp_packet *, -- const struct eth_addr eth_src, -- const struct eth_addr eth_dst, -- const struct in6_addr *ipv6_src, -- const struct in6_addr *ipv6_dst, -- uint8_t cur_hop_limit, uint8_t mo_flags, -- ovs_be16 router_lt, ovs_be32 reachable_time, -- ovs_be32 retrans_timer, uint32_t mtu); --void packet_put_ra_prefix_opt(struct dp_packet *, -- uint8_t plen, uint8_t la_flags, -- ovs_be32 valid_lifetime, -- ovs_be32 preferred_lifetime, -- const ovs_be128 router_prefix); --uint32_t packet_csum_pseudoheader(const struct ip_header *); --void IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6); -- --#define DNS_HEADER_LEN 12 --struct dns_header { -- ovs_be16 id; -- uint8_t lo_flag; /* QR (1), OPCODE (4), AA (1), TC (1) and RD (1) */ -- uint8_t hi_flag; /* RA (1), Z (3) and RCODE (4) */ -- ovs_be16 qdcount; /* Num of entries in the question section. */ -- ovs_be16 ancount; /* Num of resource records in the answer section. */ -- -- /* Num of name server records in the authority record section. */ -- ovs_be16 nscount; -- -- /* Num of resource records in the additional records section. */ -- ovs_be16 arcount; --}; -- --BUILD_ASSERT_DECL(DNS_HEADER_LEN == sizeof(struct dns_header)); -- --#define DNS_QUERY_TYPE_A 0x01 --#define DNS_QUERY_TYPE_AAAA 0x1c --#define DNS_QUERY_TYPE_ANY 0xff -- --#define DNS_CLASS_IN 0x01 --#define DNS_DEFAULT_RR_TTL 3600 -- --#endif /* packets.h */ -Index: openvswitch-2.17.2/include/internal/packets.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/packets.h -@@ -0,0 +1,1671 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef PACKETS_H -+#define PACKETS_H 1 -+ -+#include -+#include -+#include -+#include -+#include "openvswitch/compiler.h" -+#include "openvswitch/geneve.h" -+#include "openvswitch/packets.h" -+#include "openvswitch/types.h" -+#include "openvswitch/nsh.h" -+#include "odp-netlink.h" -+#include "internal/random.h" -+#include "internal/hash.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" -+#include "internal/timeval.h" -+ -+struct dp_packet; -+struct conn; -+struct ds; -+ -+/* Purely internal to OVS userspace. These flags should never be exposed to -+ * the outside world and so aren't included in the flags mask. */ -+ -+/* Tunnel information is in userspace datapath format. */ -+#define FLOW_TNL_F_UDPIF (1 << 4) -+ -+static inline bool ipv6_addr_is_set(const struct in6_addr *addr); -+ -+static inline bool -+flow_tnl_dst_is_set(const struct flow_tnl *tnl) -+{ -+ return tnl->ip_dst || ipv6_addr_is_set(&tnl->ipv6_dst); -+} -+ -+static inline bool -+flow_tnl_src_is_set(const struct flow_tnl *tnl) -+{ -+ return tnl->ip_src || ipv6_addr_is_set(&tnl->ipv6_src); -+} -+ -+struct in6_addr flow_tnl_dst(const struct flow_tnl *tnl); -+struct in6_addr flow_tnl_src(const struct flow_tnl *tnl); -+ -+/* Returns an offset to 'src' covering all the meaningful fields in 'src'. */ -+static inline size_t -+flow_tnl_size(const struct flow_tnl *src) -+{ -+ if (!flow_tnl_dst_is_set(src)) { -+ /* Covers ip_dst and ipv6_dst only. */ -+ return offsetof(struct flow_tnl, ip_src); -+ } -+ if (src->flags & FLOW_TNL_F_UDPIF) { -+ /* Datapath format, cover all options we have. */ -+ return offsetof(struct flow_tnl, metadata.opts) -+ + src->metadata.present.len; -+ } -+ if (!src->metadata.present.map) { -+ /* No TLVs, opts is irrelevant. */ -+ return offsetof(struct flow_tnl, metadata.opts); -+ } -+ /* Have decoded TLVs, opts is relevant. */ -+ return sizeof *src; -+} -+ -+/* Copy flow_tnl, but avoid copying unused portions of tun_metadata. Unused -+ * data in 'dst' is NOT cleared, so this must not be used in cases where the -+ * uninitialized portion may be hashed over. */ -+static inline void -+flow_tnl_copy__(struct flow_tnl *dst, const struct flow_tnl *src) -+{ -+ memcpy(dst, src, flow_tnl_size(src)); -+} -+ -+static inline bool -+flow_tnl_equal(const struct flow_tnl *a, const struct flow_tnl *b) -+{ -+ size_t a_size = flow_tnl_size(a); -+ -+ return a_size == flow_tnl_size(b) && !memcmp(a, b, a_size); -+} -+ -+/* Datapath packet metadata */ -+struct pkt_metadata { -+PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0, -+ uint32_t recirc_id; /* Recirculation id carried with the -+ recirculating packets. 0 for packets -+ received from the wire. */ -+ uint32_t dp_hash; /* hash value computed by the recirculation -+ action. */ -+ uint32_t skb_priority; /* Packet priority for QoS. */ -+ uint32_t pkt_mark; /* Packet mark. */ -+ uint8_t ct_state; /* Connection state. */ -+ bool ct_orig_tuple_ipv6; -+ uint16_t ct_zone; /* Connection zone. */ -+ uint32_t ct_mark; /* Connection mark. */ -+ ovs_u128 ct_label; /* Connection label. */ -+ union flow_in_port in_port; /* Input port. */ -+ odp_port_t orig_in_port; /* Originating in_port for tunneled packets */ -+ struct conn *conn; /* Cached conntrack connection. */ -+ bool reply; /* True if reply direction. */ -+ bool icmp_related; /* True if ICMP related. */ -+); -+ -+PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline1, -+ union { /* Populated only for non-zero 'ct_state'. */ -+ struct ovs_key_ct_tuple_ipv4 ipv4; -+ struct ovs_key_ct_tuple_ipv6 ipv6; /* Used only if */ -+ } ct_orig_tuple; /* 'ct_orig_tuple_ipv6' is set */ -+); -+ -+PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline2, -+ struct flow_tnl tunnel; /* Encapsulating tunnel parameters. Note that -+ * if 'ip_dst' == 0, the rest of the fields may -+ * be uninitialized. */ -+); -+}; -+ -+BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline0) == 0); -+BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline1) == -+ CACHE_LINE_SIZE); -+BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline2) == -+ 2 * CACHE_LINE_SIZE); -+ -+static inline void -+pkt_metadata_init_tnl(struct pkt_metadata *md) -+{ -+ odp_port_t orig_in_port; -+ -+ /* Zero up through the tunnel metadata options. The length and table -+ * are before this and as long as they are empty, the options won't -+ * be looked at. Keep the orig_in_port field. */ -+ orig_in_port = md->in_port.odp_port; -+ memset(md, 0, offsetof(struct pkt_metadata, tunnel.metadata.opts)); -+ md->orig_in_port = orig_in_port; -+} -+ -+static inline void -+pkt_metadata_init_conn(struct pkt_metadata *md) -+{ -+ md->conn = NULL; -+} -+ -+static inline void -+pkt_metadata_init(struct pkt_metadata *md, odp_port_t port) -+{ -+ /* This is called for every packet in userspace datapath and affects -+ * performance if all the metadata is initialized. Hence, fields should -+ * only be zeroed out when necessary. -+ * -+ * Initialize only till ct_state. Once the ct_state is zeroed out rest -+ * of ct fields will not be looked at unless ct_state != 0. -+ */ -+ memset(md, 0, offsetof(struct pkt_metadata, ct_orig_tuple_ipv6)); -+ -+ /* It can be expensive to zero out all of the tunnel metadata. However, -+ * we can just zero out ip_dst and the rest of the data will never be -+ * looked at. */ -+ md->tunnel.ip_dst = 0; -+ md->tunnel.ipv6_dst = in6addr_any; -+ md->in_port.odp_port = port; -+ md->orig_in_port = port; -+ md->conn = NULL; -+} -+ -+/* This function prefetches the cachelines touched by pkt_metadata_init() -+ * and pkt_metadata_init_tnl(). For performance reasons the two functions -+ * should be kept in sync. */ -+static inline void -+pkt_metadata_prefetch_init(struct pkt_metadata *md) -+{ -+ /* Prefetch cacheline0 as members till ct_state and odp_port will -+ * be initialized later in pkt_metadata_init(). */ -+ OVS_PREFETCH(md->cacheline0); -+ -+ /* Prefetch cacheline1 as members of this cacheline will be zeroed out -+ * in pkt_metadata_init_tnl(). */ -+ OVS_PREFETCH(md->cacheline1); -+ -+ /* Prefetch cachline2 as ip_dst & ipv6_dst fields will be initialized. */ -+ OVS_PREFETCH(md->cacheline2); -+} -+ -+bool dpid_from_string(const char *s, uint64_t *dpidp); -+ -+#define ETH_ADDR_LEN 6 -+ -+static const struct eth_addr eth_addr_broadcast OVS_UNUSED -+ = ETH_ADDR_C(ff,ff,ff,ff,ff,ff); -+ -+static const struct eth_addr eth_addr_exact OVS_UNUSED -+ = ETH_ADDR_C(ff,ff,ff,ff,ff,ff); -+ -+static const struct eth_addr eth_addr_zero OVS_UNUSED -+ = ETH_ADDR_C(00,00,00,00,00,00); -+static const struct eth_addr64 eth_addr64_zero OVS_UNUSED -+ = ETH_ADDR64_C(00,00,00,00,00,00,00,00); -+ -+static const struct eth_addr eth_addr_stp OVS_UNUSED -+ = ETH_ADDR_C(01,80,c2,00,00,00); -+ -+static const struct eth_addr eth_addr_lacp OVS_UNUSED -+ = ETH_ADDR_C(01,80,c2,00,00,02); -+ -+static const struct eth_addr eth_addr_bfd OVS_UNUSED -+ = ETH_ADDR_C(00,23,20,00,00,01); -+ -+static inline bool eth_addr_is_broadcast(const struct eth_addr a) -+{ -+ return (a.be16[0] & a.be16[1] & a.be16[2]) == htons(0xffff); -+} -+ -+static inline bool eth_addr_is_multicast(const struct eth_addr a) -+{ -+ return a.ea[0] & 1; -+} -+ -+static inline bool eth_addr_is_local(const struct eth_addr a) -+{ -+ /* Local if it is either a locally administered address or a Nicira random -+ * address. */ -+ return a.ea[0] & 2 -+ || (a.be16[0] == htons(0x0023) -+ && (a.be16[1] & htons(0xff80)) == htons(0x2080)); -+} -+static inline bool eth_addr_is_zero(const struct eth_addr a) -+{ -+ return !(a.be16[0] | a.be16[1] | a.be16[2]); -+} -+static inline bool eth_addr64_is_zero(const struct eth_addr64 a) -+{ -+ return !(a.be16[0] | a.be16[1] | a.be16[2] | a.be16[3]); -+} -+ -+static inline int eth_mask_is_exact(const struct eth_addr a) -+{ -+ return (a.be16[0] & a.be16[1] & a.be16[2]) == htons(0xffff); -+} -+ -+static inline int eth_addr_compare_3way(const struct eth_addr a, -+ const struct eth_addr b) -+{ -+ return memcmp(&a, &b, sizeof a); -+} -+static inline int eth_addr64_compare_3way(const struct eth_addr64 a, -+ const struct eth_addr64 b) -+{ -+ return memcmp(&a, &b, sizeof a); -+} -+ -+static inline bool eth_addr_equals(const struct eth_addr a, -+ const struct eth_addr b) -+{ -+ return !eth_addr_compare_3way(a, b); -+} -+static inline bool eth_addr64_equals(const struct eth_addr64 a, -+ const struct eth_addr64 b) -+{ -+ return !eth_addr64_compare_3way(a, b); -+} -+ -+static inline bool eth_addr_equal_except(const struct eth_addr a, -+ const struct eth_addr b, -+ const struct eth_addr mask) -+{ -+ return !(((a.be16[0] ^ b.be16[0]) & mask.be16[0]) -+ || ((a.be16[1] ^ b.be16[1]) & mask.be16[1]) -+ || ((a.be16[2] ^ b.be16[2]) & mask.be16[2])); -+} -+ -+uint64_t eth_addr_to_uint64(const struct eth_addr ea); -+ -+static inline uint64_t eth_addr_vlan_to_uint64(const struct eth_addr ea, -+ uint16_t vlan) -+{ -+ return (((uint64_t)vlan << 48) | eth_addr_to_uint64(ea)); -+} -+ -+void eth_addr_from_uint64(uint64_t x, struct eth_addr *ea); -+ -+static inline struct eth_addr eth_addr_invert(const struct eth_addr src) -+{ -+ struct eth_addr dst; -+ -+ for (int i = 0; i < ARRAY_SIZE(src.be16); i++) { -+ dst.be16[i] = ~src.be16[i]; -+ } -+ -+ return dst; -+} -+ -+void eth_addr_mark_random(struct eth_addr *ea); -+ -+static inline void eth_addr_random(struct eth_addr *ea) -+{ -+ random_bytes((uint8_t *)ea, sizeof *ea); -+ eth_addr_mark_random(ea); -+} -+ -+static inline void eth_addr_nicira_random(struct eth_addr *ea) -+{ -+ eth_addr_random(ea); -+ -+ /* Set the OUI to the Nicira one. */ -+ ea->ea[0] = 0x00; -+ ea->ea[1] = 0x23; -+ ea->ea[2] = 0x20; -+ -+ /* Set the top bit to indicate random Nicira address. */ -+ ea->ea[3] |= 0x80; -+} -+static inline uint32_t hash_mac(const struct eth_addr ea, -+ const uint16_t vlan, const uint32_t basis) -+{ -+ return hash_uint64_basis(eth_addr_vlan_to_uint64(ea, vlan), basis); -+} -+ -+bool eth_addr_is_reserved(const struct eth_addr); -+bool eth_addr_from_string(const char *, struct eth_addr *); -+ -+void compose_rarp(struct dp_packet *, const struct eth_addr); -+ -+void eth_push_vlan(struct dp_packet *, ovs_be16 tpid, ovs_be16 tci); -+void eth_pop_vlan(struct dp_packet *); -+ -+const char *eth_from_hex(const char *hex, struct dp_packet **packetp); -+void eth_format_masked(const struct eth_addr ea, -+ const struct eth_addr *mask, struct ds *s); -+ -+void set_mpls_lse(struct dp_packet *, ovs_be32 label); -+void push_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse); -+void pop_mpls(struct dp_packet *, ovs_be16 ethtype); -+ -+void set_mpls_lse_ttl(ovs_be32 *lse, uint8_t ttl); -+void set_mpls_lse_tc(ovs_be32 *lse, uint8_t tc); -+void set_mpls_lse_label(ovs_be32 *lse, ovs_be32 label); -+void set_mpls_lse_bos(ovs_be32 *lse, uint8_t bos); -+ovs_be32 set_mpls_lse_values(uint8_t ttl, uint8_t tc, uint8_t bos, -+ ovs_be32 label); -+void add_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse, -+ bool l3_encap); -+ -+/* Example: -+ * -+ * struct eth_addr mac; -+ * [...] -+ * printf("The Ethernet address is "ETH_ADDR_FMT"\n", ETH_ADDR_ARGS(mac)); -+ * -+ */ -+#define ETH_ADDR_FMT \ -+ "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8 -+#define ETH_ADDR_ARGS(EA) ETH_ADDR_BYTES_ARGS((EA).ea) -+#define ETH_ADDR_BYTES_ARGS(EAB) \ -+ (EAB)[0], (EAB)[1], (EAB)[2], (EAB)[3], (EAB)[4], (EAB)[5] -+#define ETH_ADDR_STRLEN 17 -+ -+/* Example: -+ * -+ * struct eth_addr64 eui64; -+ * [...] -+ * printf("The EUI-64 address is "ETH_ADDR64_FMT"\n", ETH_ADDR64_ARGS(mac)); -+ * -+ */ -+#define ETH_ADDR64_FMT \ -+ "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":" \ -+ "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8 -+#define ETH_ADDR64_ARGS(EA) ETH_ADDR64_BYTES_ARGS((EA).ea64) -+#define ETH_ADDR64_BYTES_ARGS(EAB) \ -+ (EAB)[0], (EAB)[1], (EAB)[2], (EAB)[3], \ -+ (EAB)[4], (EAB)[5], (EAB)[6], (EAB)[7] -+#define ETH_ADDR64_STRLEN 23 -+ -+/* Example: -+ * -+ * char *string = "1 00:11:22:33:44:55 2"; -+ * struct eth_addr mac; -+ * int a, b; -+ * -+ * if (ovs_scan(string, "%d"ETH_ADDR_SCAN_FMT"%d", -+ * &a, ETH_ADDR_SCAN_ARGS(mac), &b)) { -+ * ... -+ * } -+ */ -+#define ETH_ADDR_SCAN_FMT "%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8 -+#define ETH_ADDR_SCAN_ARGS(EA) \ -+ &(EA).ea[0], &(EA).ea[1], &(EA).ea[2], &(EA).ea[3], &(EA).ea[4], &(EA).ea[5] -+ -+#define ETH_TYPE_IP 0x0800 -+#define ETH_TYPE_ARP 0x0806 -+#define ETH_TYPE_TEB 0x6558 -+#define ETH_TYPE_VLAN_8021Q 0x8100 -+#define ETH_TYPE_VLAN ETH_TYPE_VLAN_8021Q -+#define ETH_TYPE_VLAN_8021AD 0x88a8 -+#define ETH_TYPE_IPV6 0x86dd -+#define ETH_TYPE_LACP 0x8809 -+#define ETH_TYPE_RARP 0x8035 -+#define ETH_TYPE_MPLS 0x8847 -+#define ETH_TYPE_MPLS_MCAST 0x8848 -+#define ETH_TYPE_NSH 0x894f -+#define ETH_TYPE_ERSPAN1 0x88be /* version 1 type II */ -+#define ETH_TYPE_ERSPAN2 0x22eb /* version 2 type III */ -+ -+static inline bool eth_type_mpls(ovs_be16 eth_type) -+{ -+ return eth_type == htons(ETH_TYPE_MPLS) || -+ eth_type == htons(ETH_TYPE_MPLS_MCAST); -+} -+ -+static inline bool eth_type_vlan(ovs_be16 eth_type) -+{ -+ return eth_type == htons(ETH_TYPE_VLAN_8021Q) || -+ eth_type == htons(ETH_TYPE_VLAN_8021AD); -+} -+ -+ -+/* Minimum value for an Ethernet type. Values below this are IEEE 802.2 frame -+ * lengths. */ -+#define ETH_TYPE_MIN 0x600 -+ -+#define ETH_HEADER_LEN 14 -+#define ETH_PAYLOAD_MIN 46 -+#define ETH_PAYLOAD_MAX 1500 -+#define ETH_TOTAL_MIN (ETH_HEADER_LEN + ETH_PAYLOAD_MIN) -+#define ETH_TOTAL_MAX (ETH_HEADER_LEN + ETH_PAYLOAD_MAX) -+#define ETH_VLAN_TOTAL_MAX (ETH_HEADER_LEN + VLAN_HEADER_LEN + ETH_PAYLOAD_MAX) -+struct eth_header { -+ struct eth_addr eth_dst; -+ struct eth_addr eth_src; -+ ovs_be16 eth_type; -+}; -+BUILD_ASSERT_DECL(ETH_HEADER_LEN == sizeof(struct eth_header)); -+ -+void push_eth(struct dp_packet *packet, const struct eth_addr *dst, -+ const struct eth_addr *src); -+void pop_eth(struct dp_packet *packet); -+ -+void push_nsh(struct dp_packet *packet, const struct nsh_hdr *nsh_hdr_src); -+bool pop_nsh(struct dp_packet *packet); -+ -+#define LLC_DSAP_SNAP 0xaa -+#define LLC_SSAP_SNAP 0xaa -+#define LLC_CNTL_SNAP 3 -+ -+#define LLC_HEADER_LEN 3 -+struct llc_header { -+ uint8_t llc_dsap; -+ uint8_t llc_ssap; -+ uint8_t llc_cntl; -+}; -+BUILD_ASSERT_DECL(LLC_HEADER_LEN == sizeof(struct llc_header)); -+ -+/* LLC field values used for STP frames. */ -+#define STP_LLC_SSAP 0x42 -+#define STP_LLC_DSAP 0x42 -+#define STP_LLC_CNTL 0x03 -+ -+#define SNAP_ORG_ETHERNET "\0\0" /* The compiler adds a null byte, so -+ sizeof(SNAP_ORG_ETHERNET) == 3. */ -+#define SNAP_HEADER_LEN 5 -+OVS_PACKED( -+struct snap_header { -+ uint8_t snap_org[3]; -+ ovs_be16 snap_type; -+}); -+BUILD_ASSERT_DECL(SNAP_HEADER_LEN == sizeof(struct snap_header)); -+ -+#define LLC_SNAP_HEADER_LEN (LLC_HEADER_LEN + SNAP_HEADER_LEN) -+OVS_PACKED( -+struct llc_snap_header { -+ struct llc_header llc; -+ struct snap_header snap; -+}); -+BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); -+ -+#define VLAN_VID_MASK 0x0fff -+#define VLAN_VID_SHIFT 0 -+ -+#define VLAN_PCP_MASK 0xe000 -+#define VLAN_PCP_SHIFT 13 -+ -+#define VLAN_CFI 0x1000 -+#define VLAN_CFI_SHIFT 12 -+ -+/* Given the vlan_tci field from an 802.1Q header, in network byte order, -+ * returns the VLAN ID in host byte order. */ -+static inline uint16_t -+vlan_tci_to_vid(ovs_be16 vlan_tci) -+{ -+ return (ntohs(vlan_tci) & VLAN_VID_MASK) >> VLAN_VID_SHIFT; -+} -+ -+/* Given the vlan_tci field from an 802.1Q header, in network byte order, -+ * returns the priority code point (PCP) in host byte order. */ -+static inline int -+vlan_tci_to_pcp(ovs_be16 vlan_tci) -+{ -+ return (ntohs(vlan_tci) & VLAN_PCP_MASK) >> VLAN_PCP_SHIFT; -+} -+ -+/* Given the vlan_tci field from an 802.1Q header, in network byte order, -+ * returns the Canonical Format Indicator (CFI). */ -+static inline int -+vlan_tci_to_cfi(ovs_be16 vlan_tci) -+{ -+ return (vlan_tci & htons(VLAN_CFI)) != 0; -+} -+ -+#define VLAN_HEADER_LEN 4 -+struct vlan_header { -+ ovs_be16 vlan_tci; /* Lowest 12 bits are VLAN ID. */ -+ ovs_be16 vlan_next_type; -+}; -+BUILD_ASSERT_DECL(VLAN_HEADER_LEN == sizeof(struct vlan_header)); -+ -+#define VLAN_ETH_HEADER_LEN (ETH_HEADER_LEN + VLAN_HEADER_LEN) -+struct vlan_eth_header { -+ struct eth_addr veth_dst; -+ struct eth_addr veth_src; -+ ovs_be16 veth_type; /* Always htons(ETH_TYPE_VLAN). */ -+ ovs_be16 veth_tci; /* Lowest 12 bits are VLAN ID. */ -+ ovs_be16 veth_next_type; -+}; -+BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); -+ -+/* MPLS related definitions */ -+#define MPLS_TTL_MASK 0x000000ff -+#define MPLS_TTL_SHIFT 0 -+ -+#define MPLS_BOS_MASK 0x00000100 -+#define MPLS_BOS_SHIFT 8 -+ -+#define MPLS_TC_MASK 0x00000e00 -+#define MPLS_TC_SHIFT 9 -+ -+#define MPLS_LABEL_MASK 0xfffff000 -+#define MPLS_LABEL_SHIFT 12 -+ -+#define MPLS_HLEN 4 -+ -+struct mpls_hdr { -+ ovs_16aligned_be32 mpls_lse; -+}; -+BUILD_ASSERT_DECL(MPLS_HLEN == sizeof(struct mpls_hdr)); -+ -+/* Given a mpls label stack entry in network byte order -+ * return mpls label in host byte order */ -+static inline uint32_t -+mpls_lse_to_label(ovs_be32 mpls_lse) -+{ -+ return (ntohl(mpls_lse) & MPLS_LABEL_MASK) >> MPLS_LABEL_SHIFT; -+} -+ -+/* Given a mpls label stack entry in network byte order -+ * return mpls tc */ -+static inline uint8_t -+mpls_lse_to_tc(ovs_be32 mpls_lse) -+{ -+ return (ntohl(mpls_lse) & MPLS_TC_MASK) >> MPLS_TC_SHIFT; -+} -+ -+/* Given a mpls label stack entry in network byte order -+ * return mpls ttl */ -+static inline uint8_t -+mpls_lse_to_ttl(ovs_be32 mpls_lse) -+{ -+ return (ntohl(mpls_lse) & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT; -+} -+ -+/* Set label in mpls lse. */ -+static inline void -+flow_set_mpls_lse_label(ovs_be32 *mpls_lse, uint32_t label) -+{ -+ *mpls_lse &= ~htonl(MPLS_LABEL_MASK); -+ *mpls_lse |= htonl(label << MPLS_LABEL_SHIFT); -+} -+ -+/* Set TC in mpls lse. */ -+static inline void -+flow_set_mpls_lse_tc(ovs_be32 *mpls_lse, uint8_t tc) -+{ -+ *mpls_lse &= ~htonl(MPLS_TC_MASK); -+ *mpls_lse |= htonl((tc & 0x7) << MPLS_TC_SHIFT); -+} -+ -+/* Set BOS in mpls lse. */ -+static inline void -+flow_set_mpls_lse_bos(ovs_be32 *mpls_lse, uint8_t bos) -+{ -+ *mpls_lse &= ~htonl(MPLS_BOS_MASK); -+ *mpls_lse |= htonl((bos & 0x1) << MPLS_BOS_SHIFT); -+} -+ -+/* Set TTL in mpls lse. */ -+static inline void -+flow_set_mpls_lse_ttl(ovs_be32 *mpls_lse, uint8_t ttl) -+{ -+ *mpls_lse &= ~htonl(MPLS_TTL_MASK); -+ *mpls_lse |= htonl(ttl << MPLS_TTL_SHIFT); -+} -+ -+/* Given a mpls label stack entry in network byte order -+ * return mpls BoS bit */ -+static inline uint8_t -+mpls_lse_to_bos(ovs_be32 mpls_lse) -+{ -+ return (mpls_lse & htonl(MPLS_BOS_MASK)) != 0; -+} -+ -+#define IP_FMT "%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32 -+#define IP_ARGS(ip) \ -+ ntohl(ip) >> 24, \ -+ (ntohl(ip) >> 16) & 0xff, \ -+ (ntohl(ip) >> 8) & 0xff, \ -+ ntohl(ip) & 0xff -+ -+/* Example: -+ * -+ * char *string = "1 33.44.55.66 2"; -+ * ovs_be32 ip; -+ * int a, b; -+ * -+ * if (ovs_scan(string, "%d"IP_SCAN_FMT"%d", &a, IP_SCAN_ARGS(&ip), &b)) { -+ * ... -+ * } -+ */ -+#define IP_SCAN_FMT "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8 -+#define IP_SCAN_ARGS(ip) \ -+ ((void) (ovs_be32) *(ip), &((uint8_t *) ip)[0]), \ -+ &((uint8_t *) ip)[1], \ -+ &((uint8_t *) ip)[2], \ -+ &((uint8_t *) ip)[3] -+ -+#define IP_PORT_SCAN_FMT "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8":%"SCNu16 -+#define IP_PORT_SCAN_ARGS(ip, port) \ -+ ((void) (ovs_be32) *(ip), &((uint8_t *) ip)[0]), \ -+ &((uint8_t *) ip)[1], \ -+ &((uint8_t *) ip)[2], \ -+ &((uint8_t *) ip)[3], \ -+ ((void) (ovs_be16) *(port), (uint16_t *) port) -+ -+/* Returns true if 'netmask' is a CIDR netmask, that is, if it consists of N -+ * high-order 1-bits and 32-N low-order 0-bits. */ -+static inline bool -+ip_is_cidr(ovs_be32 netmask) -+{ -+ uint32_t x = ~ntohl(netmask); -+ return !(x & (x + 1)); -+} -+static inline bool -+ip_is_multicast(ovs_be32 ip) -+{ -+ return (ip & htonl(0xf0000000)) == htonl(0xe0000000); -+} -+static inline bool -+ip_is_local_multicast(ovs_be32 ip) -+{ -+ return (ip & htonl(0xffffff00)) == htonl(0xe0000000); -+} -+int ip_count_cidr_bits(ovs_be32 netmask); -+void ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *); -+bool ip_parse(const char *s, ovs_be32 *ip); -+char *ip_parse_port(const char *s, ovs_be32 *ip, ovs_be16 *port) -+ OVS_WARN_UNUSED_RESULT; -+char *ip_parse_masked(const char *s, ovs_be32 *ip, ovs_be32 *mask) -+ OVS_WARN_UNUSED_RESULT; -+char *ip_parse_cidr(const char *s, ovs_be32 *ip, unsigned int *plen) -+ OVS_WARN_UNUSED_RESULT; -+char *ip_parse_masked_len(const char *s, int *n, ovs_be32 *ip, ovs_be32 *mask) -+ OVS_WARN_UNUSED_RESULT; -+char *ip_parse_cidr_len(const char *s, int *n, ovs_be32 *ip, -+ unsigned int *plen) -+ OVS_WARN_UNUSED_RESULT; -+ -+#define IP_VER(ip_ihl_ver) ((ip_ihl_ver) >> 4) -+#define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15) -+#define IP_IHL_VER(ihl, ver) (((ver) << 4) | (ihl)) -+ -+#ifndef IPPROTO_SCTP -+#define IPPROTO_SCTP 132 -+#endif -+ -+#ifndef IPPROTO_DCCP -+#define IPPROTO_DCCP 33 -+#endif -+ -+#ifndef IPPROTO_IGMP -+#define IPPROTO_IGMP 2 -+#endif -+ -+#ifndef IPPROTO_UDPLITE -+#define IPPROTO_UDPLITE 136 -+#endif -+ -+/* TOS fields. */ -+#define IP_ECN_NOT_ECT 0x0 -+#define IP_ECN_ECT_1 0x01 -+#define IP_ECN_ECT_0 0x02 -+#define IP_ECN_CE 0x03 -+#define IP_ECN_MASK 0x03 -+#define IP_DSCP_CS6 0xc0 -+#define IP_DSCP_MASK 0xfc -+ -+static inline int -+IP_ECN_is_ce(uint8_t dsfield) -+{ -+ return (dsfield & IP_ECN_MASK) == IP_ECN_CE; -+} -+ -+#define IP_VERSION 4 -+ -+#define IP_DONT_FRAGMENT 0x4000 /* Don't fragment. */ -+#define IP_MORE_FRAGMENTS 0x2000 /* More fragments. */ -+#define IP_FRAG_OFF_MASK 0x1fff /* Fragment offset. */ -+#define IP_IS_FRAGMENT(ip_frag_off) \ -+ ((ip_frag_off) & htons(IP_MORE_FRAGMENTS | IP_FRAG_OFF_MASK)) -+ -+#define IP_HEADER_LEN 20 -+struct ip_header { -+ uint8_t ip_ihl_ver; -+ uint8_t ip_tos; -+ ovs_be16 ip_tot_len; -+ ovs_be16 ip_id; -+ ovs_be16 ip_frag_off; -+ uint8_t ip_ttl; -+ uint8_t ip_proto; -+ ovs_be16 ip_csum; -+ ovs_16aligned_be32 ip_src; -+ ovs_16aligned_be32 ip_dst; -+}; -+BUILD_ASSERT_DECL(IP_HEADER_LEN == sizeof(struct ip_header)); -+ -+/* ICMPv4 types. */ -+#define ICMP4_ECHO_REPLY 0 -+#define ICMP4_DST_UNREACH 3 -+#define ICMP4_SOURCEQUENCH 4 -+#define ICMP4_REDIRECT 5 -+#define ICMP4_ECHO_REQUEST 8 -+#define ICMP4_TIME_EXCEEDED 11 -+#define ICMP4_PARAM_PROB 12 -+#define ICMP4_TIMESTAMP 13 -+#define ICMP4_TIMESTAMPREPLY 14 -+#define ICMP4_INFOREQUEST 15 -+#define ICMP4_INFOREPLY 16 -+ -+#define ICMP_HEADER_LEN 8 -+struct icmp_header { -+ uint8_t icmp_type; -+ uint8_t icmp_code; -+ ovs_be16 icmp_csum; -+ union { -+ struct { -+ ovs_be16 id; -+ ovs_be16 seq; -+ } echo; -+ struct { -+ ovs_be16 empty; -+ ovs_be16 mtu; -+ } frag; -+ ovs_16aligned_be32 gateway; -+ } icmp_fields; -+}; -+BUILD_ASSERT_DECL(ICMP_HEADER_LEN == sizeof(struct icmp_header)); -+ -+/* ICMPV4 */ -+#define ICMP_ERROR_DATA_L4_LEN 8 -+ -+#define IGMP_HEADER_LEN 8 -+struct igmp_header { -+ uint8_t igmp_type; -+ uint8_t igmp_code; -+ ovs_be16 igmp_csum; -+ ovs_16aligned_be32 group; -+}; -+BUILD_ASSERT_DECL(IGMP_HEADER_LEN == sizeof(struct igmp_header)); -+ -+#define IGMPV3_HEADER_LEN 8 -+struct igmpv3_header { -+ uint8_t type; -+ uint8_t rsvr1; -+ ovs_be16 csum; -+ ovs_be16 rsvr2; -+ ovs_be16 ngrp; -+}; -+BUILD_ASSERT_DECL(IGMPV3_HEADER_LEN == sizeof(struct igmpv3_header)); -+ -+#define IGMPV3_QUERY_HEADER_LEN 12 -+struct igmpv3_query_header { -+ uint8_t type; -+ uint8_t max_resp; -+ ovs_be16 csum; -+ ovs_16aligned_be32 group; -+ uint8_t srs_qrv; -+ uint8_t qqic; -+ ovs_be16 nsrcs; -+}; -+BUILD_ASSERT_DECL( -+ IGMPV3_QUERY_HEADER_LEN == sizeof(struct igmpv3_query_header -+)); -+ -+#define IGMPV3_RECORD_LEN 8 -+struct igmpv3_record { -+ uint8_t type; -+ uint8_t aux_len; -+ ovs_be16 nsrcs; -+ ovs_16aligned_be32 maddr; -+}; -+BUILD_ASSERT_DECL(IGMPV3_RECORD_LEN == sizeof(struct igmpv3_record)); -+ -+#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */ -+#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */ -+#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x12 */ -+#define IGMP_HOST_LEAVE_MESSAGE 0x17 -+#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x12 */ -+ -+/* -+ * IGMPv3 and MLDv2 use the same codes. -+ */ -+#define IGMPV3_MODE_IS_INCLUDE 1 -+#define IGMPV3_MODE_IS_EXCLUDE 2 -+#define IGMPV3_CHANGE_TO_INCLUDE_MODE 3 -+#define IGMPV3_CHANGE_TO_EXCLUDE_MODE 4 -+#define IGMPV3_ALLOW_NEW_SOURCES 5 -+#define IGMPV3_BLOCK_OLD_SOURCES 6 -+ -+#define SCTP_HEADER_LEN 12 -+struct sctp_header { -+ ovs_be16 sctp_src; -+ ovs_be16 sctp_dst; -+ ovs_16aligned_be32 sctp_vtag; -+ ovs_16aligned_be32 sctp_csum; -+}; -+BUILD_ASSERT_DECL(SCTP_HEADER_LEN == sizeof(struct sctp_header)); -+ -+#define UDP_HEADER_LEN 8 -+struct udp_header { -+ ovs_be16 udp_src; -+ ovs_be16 udp_dst; -+ ovs_be16 udp_len; -+ ovs_be16 udp_csum; -+}; -+BUILD_ASSERT_DECL(UDP_HEADER_LEN == sizeof(struct udp_header)); -+ -+#define ESP_HEADER_LEN 8 -+struct esp_header { -+ ovs_be32 spi; -+ ovs_be32 seq_no; -+}; -+BUILD_ASSERT_DECL(ESP_HEADER_LEN == sizeof(struct esp_header)); -+ -+#define ESP_TRAILER_LEN 2 -+struct esp_trailer { -+ uint8_t pad_len; -+ uint8_t next_hdr; -+}; -+BUILD_ASSERT_DECL(ESP_TRAILER_LEN == sizeof(struct esp_trailer)); -+ -+#define TCP_FIN 0x001 -+#define TCP_SYN 0x002 -+#define TCP_RST 0x004 -+#define TCP_PSH 0x008 -+#define TCP_ACK 0x010 -+#define TCP_URG 0x020 -+#define TCP_ECE 0x040 -+#define TCP_CWR 0x080 -+#define TCP_NS 0x100 -+ -+#define TCP_CTL(flags, offset) (htons((flags) | ((offset) << 12))) -+#define TCP_FLAGS(tcp_ctl) (ntohs(tcp_ctl) & 0x0fff) -+#define TCP_FLAGS_BE16(tcp_ctl) ((tcp_ctl) & htons(0x0fff)) -+#define TCP_OFFSET(tcp_ctl) (ntohs(tcp_ctl) >> 12) -+ -+#define TCP_HEADER_LEN 20 -+struct tcp_header { -+ ovs_be16 tcp_src; -+ ovs_be16 tcp_dst; -+ ovs_16aligned_be32 tcp_seq; -+ ovs_16aligned_be32 tcp_ack; -+ ovs_be16 tcp_ctl; -+ ovs_be16 tcp_winsz; -+ ovs_be16 tcp_csum; -+ ovs_be16 tcp_urg; -+}; -+BUILD_ASSERT_DECL(TCP_HEADER_LEN == sizeof(struct tcp_header)); -+ -+/* Connection states. -+ * -+ * Names like CS_RELATED are bit values, e.g. 1 << 2. -+ * Names like CS_RELATED_BIT are bit indexes, e.g. 2. */ -+#define CS_STATES \ -+ CS_STATE(NEW, 0, "new") \ -+ CS_STATE(ESTABLISHED, 1, "est") \ -+ CS_STATE(RELATED, 2, "rel") \ -+ CS_STATE(REPLY_DIR, 3, "rpl") \ -+ CS_STATE(INVALID, 4, "inv") \ -+ CS_STATE(TRACKED, 5, "trk") \ -+ CS_STATE(SRC_NAT, 6, "snat") \ -+ CS_STATE(DST_NAT, 7, "dnat") -+ -+enum { -+#define CS_STATE(ENUM, INDEX, NAME) \ -+ CS_##ENUM = 1 << INDEX, \ -+ CS_##ENUM##_BIT = INDEX, -+ CS_STATES -+#undef CS_STATE -+}; -+ -+/* Undefined connection state bits. */ -+enum { -+#define CS_STATE(ENUM, INDEX, NAME) +CS_##ENUM -+ CS_SUPPORTED_MASK = CS_STATES -+#undef CS_STATE -+}; -+#define CS_UNSUPPORTED_MASK (~(uint32_t)CS_SUPPORTED_MASK) -+ -+#define ARP_HRD_ETHERNET 1 -+#define ARP_PRO_IP 0x0800 -+#define ARP_OP_REQUEST 1 -+#define ARP_OP_REPLY 2 -+#define ARP_OP_RARP 3 -+ -+#define ARP_ETH_HEADER_LEN 28 -+struct arp_eth_header { -+ /* Generic members. */ -+ ovs_be16 ar_hrd; /* Hardware type. */ -+ ovs_be16 ar_pro; /* Protocol type. */ -+ uint8_t ar_hln; /* Hardware address length. */ -+ uint8_t ar_pln; /* Protocol address length. */ -+ ovs_be16 ar_op; /* Opcode. */ -+ -+ /* Ethernet+IPv4 specific members. */ -+ struct eth_addr ar_sha; /* Sender hardware address. */ -+ ovs_16aligned_be32 ar_spa; /* Sender protocol address. */ -+ struct eth_addr ar_tha; /* Target hardware address. */ -+ ovs_16aligned_be32 ar_tpa; /* Target protocol address. */ -+}; -+BUILD_ASSERT_DECL(ARP_ETH_HEADER_LEN == sizeof(struct arp_eth_header)); -+ -+#define IPV6_HEADER_LEN 40 -+ -+/* Like struct in6_addr, but whereas that struct requires 32-bit alignment on -+ * most implementations, this one only requires 16-bit alignment. */ -+union ovs_16aligned_in6_addr { -+ ovs_be16 be16[8]; -+ ovs_16aligned_be32 be32[4]; -+}; -+ -+/* Like struct ip6_hdr, but whereas that struct requires 32-bit alignment, this -+ * one only requires 16-bit alignment. */ -+struct ovs_16aligned_ip6_hdr { -+ union { -+ struct ovs_16aligned_ip6_hdrctl { -+ ovs_16aligned_be32 ip6_un1_flow; -+ ovs_be16 ip6_un1_plen; -+ uint8_t ip6_un1_nxt; -+ uint8_t ip6_un1_hlim; -+ } ip6_un1; -+ uint8_t ip6_un2_vfc; -+ } ip6_ctlun; -+ union ovs_16aligned_in6_addr ip6_src; -+ union ovs_16aligned_in6_addr ip6_dst; -+}; -+ -+/* Like struct in6_frag, but whereas that struct requires 32-bit alignment, -+ * this one only requires 16-bit alignment. */ -+struct ovs_16aligned_ip6_frag { -+ uint8_t ip6f_nxt; -+ uint8_t ip6f_reserved; -+ ovs_be16 ip6f_offlg; -+ ovs_16aligned_be32 ip6f_ident; -+}; -+ -+#define ICMP6_HEADER_LEN 4 -+struct icmp6_header { -+ uint8_t icmp6_type; -+ uint8_t icmp6_code; -+ ovs_be16 icmp6_cksum; -+}; -+BUILD_ASSERT_DECL(ICMP6_HEADER_LEN == sizeof(struct icmp6_header)); -+ -+#define ICMP6_DATA_HEADER_LEN 8 -+struct icmp6_data_header { -+ struct icmp6_header icmp6_base; -+ union { -+ ovs_16aligned_be32 be32[1]; -+ ovs_be16 be16[2]; -+ uint8_t u8[4]; -+ } icmp6_data; -+}; -+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 *, -+ const void *, uint8_t, uint16_t); -+ -+/* Neighbor Discovery option field. -+ * ND options are always a multiple of 8 bytes in size. */ -+#define ND_LLA_OPT_LEN 8 -+struct ovs_nd_lla_opt { -+ uint8_t type; /* One of ND_OPT_*_LINKADDR. */ -+ uint8_t len; -+ struct eth_addr mac; -+}; -+BUILD_ASSERT_DECL(ND_LLA_OPT_LEN == sizeof(struct ovs_nd_lla_opt)); -+ -+/* Neighbor Discovery option: Prefix Information. */ -+#define ND_PREFIX_OPT_LEN 32 -+struct ovs_nd_prefix_opt { -+ uint8_t type; /* ND_OPT_PREFIX_INFORMATION. */ -+ uint8_t len; /* Always 4. */ -+ uint8_t prefix_len; -+ uint8_t la_flags; /* ND_PREFIX_* flags. */ -+ ovs_16aligned_be32 valid_lifetime; -+ ovs_16aligned_be32 preferred_lifetime; -+ ovs_16aligned_be32 reserved; /* Always 0. */ -+ union ovs_16aligned_in6_addr prefix; -+}; -+BUILD_ASSERT_DECL(ND_PREFIX_OPT_LEN == sizeof(struct ovs_nd_prefix_opt)); -+ -+/* Neighbor Discovery option: MTU. */ -+#define ND_MTU_OPT_LEN 8 -+#define ND_MTU_DEFAULT 0 -+struct ovs_nd_mtu_opt { -+ uint8_t type; /* ND_OPT_MTU */ -+ uint8_t len; /* Always 1. */ -+ ovs_be16 reserved; /* Always 0. */ -+ ovs_16aligned_be32 mtu; -+}; -+BUILD_ASSERT_DECL(ND_MTU_OPT_LEN == sizeof(struct ovs_nd_mtu_opt)); -+ -+/* Like struct nd_msg (from ndisc.h), but whereas that struct requires 32-bit -+ * alignment, this one only requires 16-bit alignment. */ -+#define ND_MSG_LEN 24 -+struct ovs_nd_msg { -+ struct icmp6_header icmph; -+ ovs_16aligned_be32 rso_flags; -+ union ovs_16aligned_in6_addr target; -+ struct ovs_nd_lla_opt options[0]; -+}; -+BUILD_ASSERT_DECL(ND_MSG_LEN == sizeof(struct ovs_nd_msg)); -+ -+/* Neighbor Discovery packet flags. */ -+#define ND_RSO_ROUTER 0x80000000 -+#define ND_RSO_SOLICITED 0x40000000 -+#define ND_RSO_OVERRIDE 0x20000000 -+ -+#define RA_MSG_LEN 16 -+struct ovs_ra_msg { -+ struct icmp6_header icmph; -+ uint8_t cur_hop_limit; -+ uint8_t mo_flags; /* ND_RA_MANAGED_ADDRESS and ND_RA_OTHER_CONFIG flags. */ -+ ovs_be16 router_lifetime; -+ ovs_be32 reachable_time; -+ ovs_be32 retrans_timer; -+ struct ovs_nd_lla_opt options[0]; -+}; -+BUILD_ASSERT_DECL(RA_MSG_LEN == sizeof(struct ovs_ra_msg)); -+ -+#define ND_RA_MANAGED_ADDRESS 0x80 -+#define ND_RA_OTHER_CONFIG 0x40 -+ -+/* Defaults based on MaxRtrInterval and MinRtrInterval from RFC 4861 section -+ * 6.2.1 -+ */ -+#define ND_RA_MAX_INTERVAL_DEFAULT 600 -+ -+static inline int -+nd_ra_min_interval_default(int max) -+{ -+ return max >= 9 ? max / 3 : max * 3 / 4; -+} -+ -+/* -+ * Use the same struct for MLD and MLD2, naming members as the defined fields in -+ * in the corresponding version of the protocol, though they are reserved in the -+ * other one. -+ */ -+#define MLD_HEADER_LEN 8 -+struct mld_header { -+ uint8_t type; -+ uint8_t code; -+ ovs_be16 csum; -+ ovs_be16 mrd; -+ ovs_be16 ngrp; -+}; -+BUILD_ASSERT_DECL(MLD_HEADER_LEN == sizeof(struct mld_header)); -+ -+#define MLD2_RECORD_LEN 20 -+struct mld2_record { -+ uint8_t type; -+ uint8_t aux_len; -+ ovs_be16 nsrcs; -+ union ovs_16aligned_in6_addr maddr; -+}; -+BUILD_ASSERT_DECL(MLD2_RECORD_LEN == sizeof(struct mld2_record)); -+ -+#define MLD_QUERY 130 -+#define MLD_REPORT 131 -+#define MLD_DONE 132 -+#define MLD2_REPORT 143 -+ -+/* The IPv6 flow label is in the lower 20 bits of the first 32-bit word. */ -+#define IPV6_LABEL_MASK 0x000fffff -+ -+/* Example: -+ * -+ * char *string = "1 ::1 2"; -+ * char ipv6_s[IPV6_SCAN_LEN + 1]; -+ * struct in6_addr ipv6; -+ * -+ * if (ovs_scan(string, "%d"IPV6_SCAN_FMT"%d", &a, ipv6_s, &b) -+ * && inet_pton(AF_INET6, ipv6_s, &ipv6) == 1) { -+ * ... -+ * } -+ */ -+#define IPV6_SCAN_FMT "%46[0123456789abcdefABCDEF:.]" -+#define IPV6_SCAN_LEN 46 -+ -+extern const struct in6_addr in6addr_exact; -+#define IN6ADDR_EXACT_INIT { { { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \ -+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } } } -+ -+extern const struct in6_addr in6addr_all_hosts; -+#define IN6ADDR_ALL_HOSTS_INIT { { { 0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 } } } -+ -+extern const struct in6_addr in6addr_all_routers; -+#define IN6ADDR_ALL_ROUTERS_INIT { { { 0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 } } } -+ -+static inline bool ipv6_addr_equals(const struct in6_addr *a, -+ const struct in6_addr *b) -+{ -+#ifdef IN6_ARE_ADDR_EQUAL -+ return IN6_ARE_ADDR_EQUAL(a, b); -+#else -+ return !memcmp(a, b, sizeof(*a)); -+#endif -+} -+ -+/* Checks the IPv6 address in 'mask' for all zeroes. */ -+static inline bool ipv6_mask_is_any(const struct in6_addr *mask) { -+ return ipv6_addr_equals(mask, &in6addr_any); -+} -+ -+static inline bool ipv6_mask_is_exact(const struct in6_addr *mask) { -+ return ipv6_addr_equals(mask, &in6addr_exact); -+} -+ -+static inline bool ipv6_is_all_hosts(const struct in6_addr *addr) { -+ return ipv6_addr_equals(addr, &in6addr_all_hosts); -+} -+ -+static inline bool ipv6_addr_is_set(const struct in6_addr *addr) { -+ return !ipv6_addr_equals(addr, &in6addr_any); -+} -+ -+static inline bool ipv6_addr_is_multicast(const struct in6_addr *ip) { -+ return ip->s6_addr[0] == 0xff; -+} -+ -+static inline struct in6_addr -+in6_addr_mapped_ipv4(ovs_be32 ip4) -+{ -+ struct in6_addr ip6; -+ memset(&ip6, 0, sizeof(ip6)); -+ ip6.s6_addr[10] = 0xff, ip6.s6_addr[11] = 0xff; -+ memcpy(&ip6.s6_addr[12], &ip4, 4); -+ return ip6; -+} -+ -+static inline void -+in6_addr_set_mapped_ipv4(struct in6_addr *ip6, ovs_be32 ip4) -+{ -+ *ip6 = in6_addr_mapped_ipv4(ip4); -+} -+ -+static inline ovs_be32 -+in6_addr_get_mapped_ipv4(const struct in6_addr *addr) -+{ -+ union ovs_16aligned_in6_addr *taddr = -+ (union ovs_16aligned_in6_addr *) addr; -+ if (IN6_IS_ADDR_V4MAPPED(addr)) { -+ return get_16aligned_be32(&taddr->be32[3]); -+ } else { -+ return INADDR_ANY; -+ } -+} -+ -+void in6_addr_solicited_node(struct in6_addr *addr, -+ const struct in6_addr *ip6); -+ -+void in6_generate_eui64(struct eth_addr ea, const struct in6_addr *prefix, -+ struct in6_addr *lla); -+ -+void in6_generate_lla(struct eth_addr ea, struct in6_addr *lla); -+ -+/* Returns true if 'addr' is a link local address. Otherwise, false. */ -+bool in6_is_lla(struct in6_addr *addr); -+ -+void ipv6_multicast_to_ethernet(struct eth_addr *eth, -+ const struct in6_addr *ip6); -+ -+static inline bool dl_type_is_ip_any(ovs_be16 dl_type) -+{ -+ return dl_type == htons(ETH_TYPE_IP) -+ || dl_type == htons(ETH_TYPE_IPV6); -+} -+ -+/* Tunnel header */ -+ -+/* GRE protocol header */ -+struct gre_base_hdr { -+ ovs_be16 flags; -+ ovs_be16 protocol; -+}; -+ -+#define GRE_CSUM 0x8000 -+#define GRE_ROUTING 0x4000 -+#define GRE_KEY 0x2000 -+#define GRE_SEQ 0x1000 -+#define GRE_STRICT 0x0800 -+#define GRE_REC 0x0700 -+#define GRE_FLAGS 0x00F8 -+#define GRE_VERSION 0x0007 -+ -+/* -+ * ERSPAN protocol header and metadata -+ * -+ * Version 1 (Type II) header (8 octets [42:49]) -+ * 0 1 2 3 -+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Ver | VLAN | COS | En|T| Session ID | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Reserved | Index | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * -+ * -+ * ERSPAN Version 2 (Type III) header (12 octets [42:49]) -+ * 0 1 2 3 -+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Ver | VLAN | COS |BSO|T| Session ID | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Timestamp | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | SGT |P| FT | Hw ID |D|Gra|O| -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * -+ */ -+ -+/* ERSPAN has fixed 8-byte GRE header */ -+#define ERSPAN_GREHDR_LEN 8 -+#define ERSPAN_HDR(gre_base_hdr) \ -+ ((struct erspan_base_hdr *)((char *)gre_base_hdr + ERSPAN_GREHDR_LEN)) -+ -+#define ERSPAN_V1_MDSIZE 4 -+#define ERSPAN_V2_MDSIZE 8 -+ -+#define ERSPAN_SID_MASK 0x03ff /* 10-bit Session ID. */ -+#define ERSPAN_IDX_MASK 0xfffff /* v1 Index */ -+#define ERSPAN_HWID_MASK 0x03f0 -+#define ERSPAN_DIR_MASK 0x0008 -+ -+struct erspan_base_hdr { -+#ifdef WORDS_BIGENDIAN -+ uint8_t ver:4, -+ vlan_upper:4; -+ uint8_t vlan:8; -+ uint8_t cos:3, -+ en:2, -+ t:1, -+ session_id_upper:2; -+ uint8_t session_id:8; -+#else -+ uint8_t vlan_upper:4, -+ ver:4; -+ uint8_t vlan:8; -+ uint8_t session_id_upper:2, -+ t:1, -+ en:2, -+ cos:3; -+ uint8_t session_id:8; -+#endif -+}; -+ -+struct erspan_md2 { -+ ovs_16aligned_be32 timestamp; -+ ovs_be16 sgt; -+#ifdef WORDS_BIGENDIAN -+ uint8_t p:1, -+ ft:5, -+ hwid_upper:2; -+ uint8_t hwid:4, -+ dir:1, -+ gra:2, -+ o:1; -+#else -+ uint8_t hwid_upper:2, -+ ft:5, -+ p:1; -+ uint8_t o:1, -+ gra:2, -+ dir:1, -+ hwid:4; -+#endif -+}; -+ -+struct erspan_metadata { -+ int version; -+ union { -+ ovs_be32 index; /* Version 1 (type II)*/ -+ struct erspan_md2 md2; /* Version 2 (type III) */ -+ } u; -+}; -+ -+static inline uint16_t get_sid(const struct erspan_base_hdr *ershdr) -+{ -+ return (ershdr->session_id_upper << 8) + ershdr->session_id; -+} -+ -+static inline void set_sid(struct erspan_base_hdr *ershdr, uint16_t id) -+{ -+ ershdr->session_id = id & 0xff; -+ ershdr->session_id_upper = (id >> 8) &0x3; -+} -+ -+static inline uint8_t get_hwid(const struct erspan_md2 *md2) -+{ -+ return (md2->hwid_upper << 4) + md2->hwid; -+} -+ -+static inline void set_hwid(struct erspan_md2 *md2, uint8_t hwid) -+{ -+ md2->hwid = hwid & 0xf; -+ md2->hwid_upper = (hwid >> 4) & 0x3; -+} -+ -+/* ERSPAN timestamp granularity -+ * 00b --> granularity = 100 microseconds -+ * 01b --> granularity = 100 nanoseconds -+ * 10b --> granularity = IEEE 1588 -+ * Here we only support 100 microseconds. -+ */ -+enum erspan_ts_gra { -+ ERSPAN_100US, -+ ERSPAN_100NS, -+ ERSPAN_IEEE1588, -+}; -+ -+static inline ovs_be32 get_erspan_ts(enum erspan_ts_gra gra) -+{ -+ ovs_be32 ts = 0; -+ -+ switch (gra) { -+ case ERSPAN_100US: -+ ts = htonl((uint32_t)(time_wall_usec() / 100)); -+ break; -+ case ERSPAN_100NS: -+ /* fall back */ -+ case ERSPAN_IEEE1588: -+ /* fall back */ -+ default: -+ OVS_NOT_REACHED(); -+ break; -+ } -+ return ts; -+} -+ -+/* -+ * GTP-U protocol header and metadata -+ * See: -+ * User Plane Protocol and Architectural Analysis on 3GPP 5G System -+ * draft-hmm-dmm-5g-uplane-analysis-00 -+ * -+ * 0 1 2 3 -+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Ver |P|R|E|S|N| Message Type| Length | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Tunnel Endpoint Identifier | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Sequence Number | N-PDU Number | Next-Ext-Hdr | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * -+ * GTP-U Flags: -+ * P: Protocol Type (Set to '1') -+ * R: Reserved Bit (Set to '0') -+ * E: Extension Header Flag (Set to '1' if extension header exists) -+ * S: Sequence Number Flag (Set to '1' if sequence number exists) -+ * N: N-PDU Number Flag (Set to '1' if N-PDU number exists) -+ * -+ * GTP-U Message Type: -+ * Indicates the type of GTP-U message. -+ * -+ * GTP-U Length: -+ * Indicates the length in octets of the payload. -+ * -+ * User payload is transmitted in G-PDU packets. -+ */ -+ -+#define GTPU_VER_MASK 0xe0 -+#define GTPU_P_MASK 0x10 -+#define GTPU_E_MASK 0x04 -+#define GTPU_S_MASK 0x02 -+ -+/* GTP-U UDP port. */ -+#define GTPU_DST_PORT 2152 -+ -+/* Default GTP-U flags: Ver = 1 and P = 1. */ -+#define GTPU_FLAGS_DEFAULT 0x30 -+ -+/* GTP-U message type for normal user plane PDU. */ -+#define GTPU_MSGTYPE_REQ 1 /* Echo Request. */ -+#define GTPU_MSGTYPE_REPL 2 /* Echo Reply. */ -+#define GTPU_MSGTYPE_GPDU 255 /* User Payload. */ -+ -+struct gtpu_metadata { -+ uint8_t flags; -+ uint8_t msgtype; -+}; -+BUILD_ASSERT_DECL(sizeof(struct gtpu_metadata) == 2); -+ -+struct gtpuhdr { -+ struct gtpu_metadata md; -+ ovs_be16 len; -+ ovs_16aligned_be32 teid; -+}; -+BUILD_ASSERT_DECL(sizeof(struct gtpuhdr) == 8); -+ -+struct gtpuhdr_opt { -+ ovs_be16 seqno; -+ uint8_t pdu_number; -+ uint8_t next_ext_type; -+}; -+BUILD_ASSERT_DECL(sizeof(struct gtpuhdr_opt) == 4); -+ -+/* VXLAN protocol header */ -+struct vxlanhdr { -+ union { -+ ovs_16aligned_be32 vx_flags; /* VXLAN flags. */ -+ struct { -+ uint8_t flags; /* VXLAN GPE flags. */ -+ uint8_t reserved[2]; /* 16 bits reserved. */ -+ uint8_t next_protocol; /* Next Protocol field for VXLAN GPE. */ -+ } vx_gpe; -+ }; -+ ovs_16aligned_be32 vx_vni; -+}; -+BUILD_ASSERT_DECL(sizeof(struct vxlanhdr) == 8); -+ -+#define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ -+ -+/* -+ * VXLAN Generic Protocol Extension (VXLAN_F_GPE): -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * |R|R|Ver|I|P|R|O| Reserved |Next Protocol | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | VXLAN Network Identifier (VNI) | Reserved | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * -+ * Ver = Version. Indicates VXLAN GPE protocol version. -+ * -+ * P = Next Protocol Bit. The P bit is set to indicate that the -+ * Next Protocol field is present. -+ * -+ * O = OAM Flag Bit. The O bit is set to indicate that the packet -+ * is an OAM packet. -+ * -+ * Next Protocol = This 8 bit field indicates the protocol header -+ * immediately following the VXLAN GPE header. -+ * -+ * https://tools.ietf.org/html/draft-ietf-nvo3-vxlan-gpe-01 -+ */ -+ -+/* Fields in struct vxlanhdr.vx_gpe.flags */ -+#define VXLAN_GPE_FLAGS_VER 0x30 /* Version. */ -+#define VXLAN_GPE_FLAGS_P 0x04 /* Next Protocol Bit. */ -+#define VXLAN_GPE_FLAGS_O 0x01 /* OAM Bit. */ -+ -+/* VXLAN-GPE header flags. */ -+#define VXLAN_HF_VER ((1U <<29) | (1U <<28)) -+#define VXLAN_HF_NP (1U <<26) -+#define VXLAN_HF_OAM (1U <<24) -+ -+#define VXLAN_GPE_USED_BITS (VXLAN_HF_VER | VXLAN_HF_NP | VXLAN_HF_OAM | \ -+ 0xff) -+ -+/* VXLAN-GPE header Next Protocol. */ -+#define VXLAN_GPE_NP_IPV4 0x01 -+#define VXLAN_GPE_NP_IPV6 0x02 -+#define VXLAN_GPE_NP_ETHERNET 0x03 -+#define VXLAN_GPE_NP_NSH 0x04 -+ -+#define VXLAN_F_GPE 0x4000 -+#define VXLAN_HF_GPE 0x04000000 -+ -+/* Input values for PACKET_TYPE macros have to be in host byte order. -+ * The _BE postfix indicates result is in network byte order. Otherwise result -+ * is in host byte order. */ -+#define PACKET_TYPE(NS, NS_TYPE) ((uint32_t) ((NS) << 16 | (NS_TYPE))) -+#define PACKET_TYPE_BE(NS, NS_TYPE) (htonl((NS) << 16 | (NS_TYPE))) -+ -+/* Returns the host byte ordered namespace of 'packet type'. */ -+static inline uint16_t -+pt_ns(ovs_be32 packet_type) -+{ -+ return ntohl(packet_type) >> 16; -+} -+ -+/* Returns the network byte ordered namespace type of 'packet type'. */ -+static inline ovs_be16 -+pt_ns_type_be(ovs_be32 packet_type) -+{ -+ return be32_to_be16(packet_type); -+} -+ -+/* Returns the host byte ordered namespace type of 'packet type'. */ -+static inline uint16_t -+pt_ns_type(ovs_be32 packet_type) -+{ -+ return ntohs(pt_ns_type_be(packet_type)); -+} -+ -+/* Well-known packet_type field values. */ -+enum packet_type { -+ PT_ETH = PACKET_TYPE(OFPHTN_ONF, 0x0000), /* Default PT: Ethernet */ -+ PT_USE_NEXT_PROTO = PACKET_TYPE(OFPHTN_ONF, 0xfffe), /* Pseudo PT for decap. */ -+ PT_IPV4 = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_IP), -+ PT_IPV6 = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_IPV6), -+ PT_MPLS = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_MPLS), -+ PT_MPLS_MC = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_MPLS_MCAST), -+ PT_NSH = PACKET_TYPE(OFPHTN_ETHERTYPE, ETH_TYPE_NSH), -+ PT_UNKNOWN = PACKET_TYPE(0xffff, 0xffff), /* Unknown packet type. */ -+}; -+ -+ -+void ipv6_format_addr(const struct in6_addr *addr, struct ds *); -+void ipv6_format_addr_bracket(const struct in6_addr *addr, struct ds *, -+ bool bracket); -+void ipv6_format_mapped(const struct in6_addr *addr, struct ds *); -+void ipv6_format_masked(const struct in6_addr *addr, -+ const struct in6_addr *mask, struct ds *); -+const char * ipv6_string_mapped(char *addr_str, const struct in6_addr *addr); -+struct in6_addr ipv6_addr_bitand(const struct in6_addr *src, -+ const struct in6_addr *mask); -+struct in6_addr ipv6_addr_bitxor(const struct in6_addr *a, -+ const struct in6_addr *b); -+bool ipv6_is_zero(const struct in6_addr *a); -+struct in6_addr ipv6_create_mask(int mask); -+int ipv6_count_cidr_bits(const struct in6_addr *netmask); -+bool ipv6_is_cidr(const struct in6_addr *netmask); -+ -+bool ipv6_parse(const char *s, struct in6_addr *ip); -+char *ipv6_parse_masked(const char *s, struct in6_addr *ipv6, -+ struct in6_addr *mask); -+char *ipv6_parse_cidr(const char *s, struct in6_addr *ip, unsigned int *plen) -+ OVS_WARN_UNUSED_RESULT; -+char *ipv6_parse_masked_len(const char *s, int *n, struct in6_addr *ipv6, -+ struct in6_addr *mask); -+char *ipv6_parse_cidr_len(const char *s, int *n, struct in6_addr *ip, -+ unsigned int *plen) -+ OVS_WARN_UNUSED_RESULT; -+ -+void *eth_compose(struct dp_packet *, const struct eth_addr eth_dst, -+ const struct eth_addr eth_src, uint16_t eth_type, -+ size_t size); -+void *snap_compose(struct dp_packet *, const struct eth_addr eth_dst, -+ const struct eth_addr eth_src, -+ unsigned int oui, uint16_t snap_type, size_t size); -+void packet_set_ipv4(struct dp_packet *, ovs_be32 src, ovs_be32 dst, uint8_t tos, -+ uint8_t ttl); -+void packet_set_ipv4_addr(struct dp_packet *packet, ovs_16aligned_be32 *addr, -+ ovs_be32 new_addr); -+void packet_set_ipv6(struct dp_packet *, const struct in6_addr *src, -+ const struct in6_addr *dst, uint8_t tc, -+ ovs_be32 fl, uint8_t hlmit); -+void packet_set_ipv6_addr(struct dp_packet *packet, uint8_t proto, -+ ovs_16aligned_be32 addr[4], -+ const struct in6_addr *new_addr, -+ bool recalculate_csum); -+void packet_set_tcp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst); -+void packet_set_udp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst); -+void packet_set_sctp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst); -+void packet_set_icmp(struct dp_packet *, uint8_t type, uint8_t code); -+void packet_set_nd(struct dp_packet *, const struct in6_addr *target, -+ const struct eth_addr sll, const struct eth_addr tll); -+void packet_set_nd_ext(struct dp_packet *packet, -+ const ovs_16aligned_be32 rso_flags, -+ const uint8_t opt_type); -+void packet_set_igmp3_query(struct dp_packet *, uint8_t max_resp, -+ ovs_be32 group, bool srs, uint8_t qrv, -+ uint8_t qqic); -+void packet_format_tcp_flags(struct ds *, uint16_t); -+const char *packet_tcp_flag_to_string(uint32_t flag); -+void *compose_ipv6(struct dp_packet *packet, uint8_t proto, -+ const struct in6_addr *src, const struct in6_addr *dst, -+ uint8_t key_tc, ovs_be32 key_fl, uint8_t key_hl, int size); -+void compose_arp__(struct dp_packet *); -+void compose_arp(struct dp_packet *, uint16_t arp_op, -+ const struct eth_addr arp_sha, -+ const struct eth_addr arp_tha, bool broadcast, -+ ovs_be32 arp_spa, ovs_be32 arp_tpa); -+void compose_nd_ns(struct dp_packet *, const struct eth_addr eth_src, -+ const struct in6_addr *ipv6_src, -+ const struct in6_addr *ipv6_dst); -+void compose_nd_na(struct dp_packet *, const struct eth_addr eth_src, -+ const struct eth_addr eth_dst, -+ const struct in6_addr *ipv6_src, -+ const struct in6_addr *ipv6_dst, -+ ovs_be32 rso_flags); -+void compose_nd_ra(struct dp_packet *, -+ const struct eth_addr eth_src, -+ const struct eth_addr eth_dst, -+ const struct in6_addr *ipv6_src, -+ const struct in6_addr *ipv6_dst, -+ uint8_t cur_hop_limit, uint8_t mo_flags, -+ ovs_be16 router_lt, ovs_be32 reachable_time, -+ ovs_be32 retrans_timer, uint32_t mtu); -+void packet_put_ra_prefix_opt(struct dp_packet *, -+ uint8_t plen, uint8_t la_flags, -+ ovs_be32 valid_lifetime, -+ ovs_be32 preferred_lifetime, -+ const ovs_be128 router_prefix); -+uint32_t packet_csum_pseudoheader(const struct ip_header *); -+void IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6); -+ -+#define DNS_HEADER_LEN 12 -+struct dns_header { -+ ovs_be16 id; -+ uint8_t lo_flag; /* QR (1), OPCODE (4), AA (1), TC (1) and RD (1) */ -+ uint8_t hi_flag; /* RA (1), Z (3) and RCODE (4) */ -+ ovs_be16 qdcount; /* Num of entries in the question section. */ -+ ovs_be16 ancount; /* Num of resource records in the answer section. */ -+ -+ /* Num of name server records in the authority record section. */ -+ ovs_be16 nscount; -+ -+ /* Num of resource records in the additional records section. */ -+ ovs_be16 arcount; -+}; -+ -+BUILD_ASSERT_DECL(DNS_HEADER_LEN == sizeof(struct dns_header)); -+ -+#define DNS_QUERY_TYPE_A 0x01 -+#define DNS_QUERY_TYPE_AAAA 0x1c -+#define DNS_QUERY_TYPE_ANY 0xff -+ -+#define DNS_CLASS_IN 0x01 -+#define DNS_DEFAULT_RR_TTL 3600 -+ -+#endif /* packets.h */ -Index: openvswitch-2.17.2/lib/pvector.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/pvector.h -+++ /dev/null -@@ -1,249 +0,0 @@ --/* -- * Copyright (c) 2014, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef PVECTOR_H --#define PVECTOR_H 1 -- --#include --#include --#include --#include "ovs-rcu.h" --#include "util.h" -- --/* Concurrent Priority Vector -- * ========================== -- * -- * Concurrent priority vector holds non-NULL pointers to objects in a -- * nondecreasing priority order and allows readers to traverse the vector -- * without being concerned about writers modifying the vector as they are -- * traversing it. -- * -- * Multiple elements of a given priority are allowed. -- * -- * The priority order is maintained as a linear vector of elements to allow -- * for efficient memory prefetching. -- * -- * Concurrency is implemented with OVS RCU so that the readers can assume -- * that once they have taken a pointer to the vector with -- * pvector_cursor_init(), the 'size' member will not decrease, so that -- * they can safely read 'size' entries from 'vector', and find that each -- * entry has a valid, non-NULL 'ptr', and the vector is in order from highest -- * to lowest 'priority'. The 'priority' values can change any time, but only -- * so that the order of the entries does not change, so readers can use -- * 'priority' values read at any time after acquisition of the vector pointer. -- * -- * Writers can concurrently add entries to the end of the vector, incrementing -- * 'size', or update the 'priority' value of an entry, but only if that does -- * not change the ordering of the entries. Writers will never change the 'ptr' -- * values, or decrement the 'size' on a copy that readers have access to. -- * -- * Most modifications are internally staged at the 'temp' vector, from which -- * they can be published at 'impl' by calling pvector_publish(). This saves -- * unnecessary memory allocations when many changes are done back-to-back. -- * 'temp' may contain NULL pointers and it may be in unsorted order. It is -- * sorted before it is published at 'impl', which also removes the NULLs from -- * the published vector. -- * -- * Since the vector is RCU protected, the entry destruction after removal must -- * be RCU postponed. Also, if it happens before changes published with -- * pvector_publish(), destruction must be double postponed, i.e., the second -- * ovsrcu_postpone() call to destruct the entry should be called from the first -- * RCU callback. This is required because readers could still obtain the -- * unmodified vector until updated version is published. -- */ -- --struct pvector_entry { -- int priority; -- void *ptr; --}; -- --struct pvector_impl { -- atomic_size_t size; /* Number of entries in the vector. */ -- size_t allocated; /* Number of allocated entries. */ -- struct pvector_entry vector[]; --}; -- --/* Concurrent priority vector. */ --struct pvector { -- OVSRCU_TYPE(struct pvector_impl *) impl; -- struct pvector_impl *temp; --}; -- --/* Initialization. */ --void pvector_init(struct pvector *); --void pvector_destroy(struct pvector *); -- --/* Insertion and deletion. These work on 'temp'. */ --void pvector_insert(struct pvector *, void *, int priority); --void pvector_change_priority(struct pvector *, void *, int priority); --void pvector_remove(struct pvector *, void *); -- --/* Make the modified pvector available for iteration. */ --static inline void pvector_publish(struct pvector *); -- --/* Count. These operate on the published pvector. */ --static inline size_t pvector_count(const struct pvector *); --static inline bool pvector_is_empty(const struct pvector *); -- --/* Iteration. -- * -- * -- * Thread-safety -- * ============= -- * -- * Iteration is safe even in a pvector that is changing concurrently. -- * Multiple writers must exclude each other via e.g., a mutex. -- * -- * Example -- * ======= -- * -- * struct my_node { -- * int data; -- * }; -- * -- * struct my_node elem1, elem2, *iter; -- * struct pvector my_pvector; -- * -- * pvector_init(&my_pvector); -- * ...add data... -- * pvector_insert(&my_pvector, &elem1, 1); -- * pvector_insert(&my_pvector, &elem2, 2); -- * ... -- * PVECTOR_FOR_EACH (iter, &my_pvector) { -- * ...operate on '*iter'... -- * ...elem2 to be seen before elem1... -- * } -- * ... -- * pvector_destroy(&my_pvector); -- * -- * There is no PVECTOR_FOR_EACH_SAFE variant as iteration is performed on RCU -- * protected instance of the priority vector. Any concurrent modifications -- * that would be disruptive for readers (such as deletions), will be performed -- * on a new instance. To see any of the modifications, a new iteration loop -- * has to be started. -- * -- * The PVECTOR_FOR_EACH_PRIORITY limits the iteration to entries with higher -- * than or equal to the given priority and allows for object lookahead. -- * -- * The iteration loop must be completed without entering the OVS RCU quiescent -- * period. That is, an old iteration loop must not be continued after any -- * blocking IO (VLOG is non-blocking, so that is OK). -- */ --struct pvector_cursor { -- size_t size; /* Number of entries in the vector. */ -- size_t entry_idx; /* Current index. */ -- const struct pvector_entry *vector; --}; -- --static inline struct pvector_cursor pvector_cursor_init(const struct pvector *, -- size_t n_ahead, -- size_t obj_size); --static inline void *pvector_cursor_next(struct pvector_cursor *, -- int lowest_priority, -- size_t n_ahead, size_t obj_size); --static inline void pvector_cursor_lookahead(const struct pvector_cursor *, -- int n, size_t size); -- --#define PVECTOR_FOR_EACH(PTR, PVECTOR) \ -- for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, 0, 0); \ -- ((PTR) = pvector_cursor_next(&cursor__, INT_MIN, 0, 0)) != NULL; ) -- --/* Loop while priority is higher than or equal to 'PRIORITY' and prefetch -- * objects of size 'SZ' 'N' objects ahead from the current object. */ --#define PVECTOR_FOR_EACH_PRIORITY(PTR, PRIORITY, N, SZ, PVECTOR) \ -- for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, N, SZ); \ -- ((PTR) = pvector_cursor_next(&cursor__, PRIORITY, N, SZ)) != NULL; ) -- --#define PVECTOR_CURSOR_FOR_EACH(PTR, CURSOR, PVECTOR) \ -- for (*(CURSOR) = pvector_cursor_init(PVECTOR, 0, 0); \ -- ((PTR) = pvector_cursor_next(CURSOR, INT_MIN, 0, 0)) != NULL; ) -- --#define PVECTOR_CURSOR_FOR_EACH_CONTINUE(PTR, CURSOR) \ -- for (; ((PTR) = pvector_cursor_next(CURSOR, INT_MIN, 0, 0)) != NULL; ) -- -- --/* Inline implementations. */ -- --static inline struct pvector_cursor --pvector_cursor_init(const struct pvector *pvec, -- size_t n_ahead, size_t obj_size) --{ -- const struct pvector_impl *impl; -- struct pvector_cursor cursor; -- size_t size; -- -- impl = ovsrcu_get(struct pvector_impl *, &pvec->impl); -- -- /* Use memory_order_acquire to ensure entry access can not be -- * reordered to happen before size read. */ -- atomic_read_explicit(&CONST_CAST(struct pvector_impl *, impl)->size, -- &size, memory_order_acquire); -- ovs_prefetch_range(impl->vector, size * sizeof impl->vector[0]); -- -- cursor.size = size; -- cursor.vector = impl->vector; -- cursor.entry_idx = -1; -- -- for (size_t i = 0; i < n_ahead; i++) { -- /* Prefetch the first objects. */ -- pvector_cursor_lookahead(&cursor, i, obj_size); -- } -- return cursor; --} -- --static inline void *pvector_cursor_next(struct pvector_cursor *cursor, -- int lowest_priority, -- size_t n_ahead, size_t obj_size) --{ -- if (++cursor->entry_idx < cursor->size && -- cursor->vector[cursor->entry_idx].priority >= lowest_priority) { -- if (n_ahead) { -- pvector_cursor_lookahead(cursor, n_ahead, obj_size); -- } -- return cursor->vector[cursor->entry_idx].ptr; -- } -- return NULL; --} -- --static inline void pvector_cursor_lookahead(const struct pvector_cursor *cursor, -- int n, size_t size) --{ -- if (cursor->entry_idx + n < cursor->size) { -- ovs_prefetch_range(cursor->vector[cursor->entry_idx + n].ptr, size); -- } --} -- --static inline size_t pvector_count(const struct pvector *pvec) --{ -- return ovsrcu_get(struct pvector_impl *, &pvec->impl)->size; --} -- --static inline bool pvector_is_empty(const struct pvector *pvec) --{ -- return pvector_count(pvec) == 0; --} -- --void pvector_publish__(struct pvector *); -- --/* Make the modified pvector available for iteration. */ --static inline void pvector_publish(struct pvector *pvec) --{ -- if (pvec->temp) { -- pvector_publish__(pvec); -- } --} -- --#endif /* pvector.h */ -Index: openvswitch-2.17.2/include/internal/pvector.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/pvector.h -@@ -0,0 +1,249 @@ -+/* -+ * Copyright (c) 2014, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef PVECTOR_H -+#define PVECTOR_H 1 -+ -+#include -+#include -+#include -+#include "openvswitch/ovs-rcu.h" -+#include "internal/util.h" -+ -+/* Concurrent Priority Vector -+ * ========================== -+ * -+ * Concurrent priority vector holds non-NULL pointers to objects in a -+ * nondecreasing priority order and allows readers to traverse the vector -+ * without being concerned about writers modifying the vector as they are -+ * traversing it. -+ * -+ * Multiple elements of a given priority are allowed. -+ * -+ * The priority order is maintained as a linear vector of elements to allow -+ * for efficient memory prefetching. -+ * -+ * Concurrency is implemented with OVS RCU so that the readers can assume -+ * that once they have taken a pointer to the vector with -+ * pvector_cursor_init(), the 'size' member will not decrease, so that -+ * they can safely read 'size' entries from 'vector', and find that each -+ * entry has a valid, non-NULL 'ptr', and the vector is in order from highest -+ * to lowest 'priority'. The 'priority' values can change any time, but only -+ * so that the order of the entries does not change, so readers can use -+ * 'priority' values read at any time after acquisition of the vector pointer. -+ * -+ * Writers can concurrently add entries to the end of the vector, incrementing -+ * 'size', or update the 'priority' value of an entry, but only if that does -+ * not change the ordering of the entries. Writers will never change the 'ptr' -+ * values, or decrement the 'size' on a copy that readers have access to. -+ * -+ * Most modifications are internally staged at the 'temp' vector, from which -+ * they can be published at 'impl' by calling pvector_publish(). This saves -+ * unnecessary memory allocations when many changes are done back-to-back. -+ * 'temp' may contain NULL pointers and it may be in unsorted order. It is -+ * sorted before it is published at 'impl', which also removes the NULLs from -+ * the published vector. -+ * -+ * Since the vector is RCU protected, the entry destruction after removal must -+ * be RCU postponed. Also, if it happens before changes published with -+ * pvector_publish(), destruction must be double postponed, i.e., the second -+ * ovsrcu_postpone() call to destruct the entry should be called from the first -+ * RCU callback. This is required because readers could still obtain the -+ * unmodified vector until updated version is published. -+ */ -+ -+struct pvector_entry { -+ int priority; -+ void *ptr; -+}; -+ -+struct pvector_impl { -+ atomic_size_t size; /* Number of entries in the vector. */ -+ size_t allocated; /* Number of allocated entries. */ -+ struct pvector_entry vector[]; -+}; -+ -+/* Concurrent priority vector. */ -+struct pvector { -+ OVSRCU_TYPE(struct pvector_impl *) impl; -+ struct pvector_impl *temp; -+}; -+ -+/* Initialization. */ -+void pvector_init(struct pvector *); -+void pvector_destroy(struct pvector *); -+ -+/* Insertion and deletion. These work on 'temp'. */ -+void pvector_insert(struct pvector *, void *, int priority); -+void pvector_change_priority(struct pvector *, void *, int priority); -+void pvector_remove(struct pvector *, void *); -+ -+/* Make the modified pvector available for iteration. */ -+static inline void pvector_publish(struct pvector *); -+ -+/* Count. These operate on the published pvector. */ -+static inline size_t pvector_count(const struct pvector *); -+static inline bool pvector_is_empty(const struct pvector *); -+ -+/* Iteration. -+ * -+ * -+ * Thread-safety -+ * ============= -+ * -+ * Iteration is safe even in a pvector that is changing concurrently. -+ * Multiple writers must exclude each other via e.g., a mutex. -+ * -+ * Example -+ * ======= -+ * -+ * struct my_node { -+ * int data; -+ * }; -+ * -+ * struct my_node elem1, elem2, *iter; -+ * struct pvector my_pvector; -+ * -+ * pvector_init(&my_pvector); -+ * ...add data... -+ * pvector_insert(&my_pvector, &elem1, 1); -+ * pvector_insert(&my_pvector, &elem2, 2); -+ * ... -+ * PVECTOR_FOR_EACH (iter, &my_pvector) { -+ * ...operate on '*iter'... -+ * ...elem2 to be seen before elem1... -+ * } -+ * ... -+ * pvector_destroy(&my_pvector); -+ * -+ * There is no PVECTOR_FOR_EACH_SAFE variant as iteration is performed on RCU -+ * protected instance of the priority vector. Any concurrent modifications -+ * that would be disruptive for readers (such as deletions), will be performed -+ * on a new instance. To see any of the modifications, a new iteration loop -+ * has to be started. -+ * -+ * The PVECTOR_FOR_EACH_PRIORITY limits the iteration to entries with higher -+ * than or equal to the given priority and allows for object lookahead. -+ * -+ * The iteration loop must be completed without entering the OVS RCU quiescent -+ * period. That is, an old iteration loop must not be continued after any -+ * blocking IO (VLOG is non-blocking, so that is OK). -+ */ -+struct pvector_cursor { -+ size_t size; /* Number of entries in the vector. */ -+ size_t entry_idx; /* Current index. */ -+ const struct pvector_entry *vector; -+}; -+ -+static inline struct pvector_cursor pvector_cursor_init(const struct pvector *, -+ size_t n_ahead, -+ size_t obj_size); -+static inline void *pvector_cursor_next(struct pvector_cursor *, -+ int lowest_priority, -+ size_t n_ahead, size_t obj_size); -+static inline void pvector_cursor_lookahead(const struct pvector_cursor *, -+ int n, size_t size); -+ -+#define PVECTOR_FOR_EACH(PTR, PVECTOR) \ -+ for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, 0, 0); \ -+ ((PTR) = pvector_cursor_next(&cursor__, INT_MIN, 0, 0)) != NULL; ) -+ -+/* Loop while priority is higher than or equal to 'PRIORITY' and prefetch -+ * objects of size 'SZ' 'N' objects ahead from the current object. */ -+#define PVECTOR_FOR_EACH_PRIORITY(PTR, PRIORITY, N, SZ, PVECTOR) \ -+ for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, N, SZ); \ -+ ((PTR) = pvector_cursor_next(&cursor__, PRIORITY, N, SZ)) != NULL; ) -+ -+#define PVECTOR_CURSOR_FOR_EACH(PTR, CURSOR, PVECTOR) \ -+ for (*(CURSOR) = pvector_cursor_init(PVECTOR, 0, 0); \ -+ ((PTR) = pvector_cursor_next(CURSOR, INT_MIN, 0, 0)) != NULL; ) -+ -+#define PVECTOR_CURSOR_FOR_EACH_CONTINUE(PTR, CURSOR) \ -+ for (; ((PTR) = pvector_cursor_next(CURSOR, INT_MIN, 0, 0)) != NULL; ) -+ -+ -+/* Inline implementations. */ -+ -+static inline struct pvector_cursor -+pvector_cursor_init(const struct pvector *pvec, -+ size_t n_ahead, size_t obj_size) -+{ -+ const struct pvector_impl *impl; -+ struct pvector_cursor cursor; -+ size_t size; -+ -+ impl = ovsrcu_get(struct pvector_impl *, &pvec->impl); -+ -+ /* Use memory_order_acquire to ensure entry access can not be -+ * reordered to happen before size read. */ -+ atomic_read_explicit(&CONST_CAST(struct pvector_impl *, impl)->size, -+ &size, memory_order_acquire); -+ ovs_prefetch_range(impl->vector, size * sizeof impl->vector[0]); -+ -+ cursor.size = size; -+ cursor.vector = impl->vector; -+ cursor.entry_idx = -1; -+ -+ for (size_t i = 0; i < n_ahead; i++) { -+ /* Prefetch the first objects. */ -+ pvector_cursor_lookahead(&cursor, i, obj_size); -+ } -+ return cursor; -+} -+ -+static inline void *pvector_cursor_next(struct pvector_cursor *cursor, -+ int lowest_priority, -+ size_t n_ahead, size_t obj_size) -+{ -+ if (++cursor->entry_idx < cursor->size && -+ cursor->vector[cursor->entry_idx].priority >= lowest_priority) { -+ if (n_ahead) { -+ pvector_cursor_lookahead(cursor, n_ahead, obj_size); -+ } -+ return cursor->vector[cursor->entry_idx].ptr; -+ } -+ return NULL; -+} -+ -+static inline void pvector_cursor_lookahead(const struct pvector_cursor *cursor, -+ int n, size_t size) -+{ -+ if (cursor->entry_idx + n < cursor->size) { -+ ovs_prefetch_range(cursor->vector[cursor->entry_idx + n].ptr, size); -+ } -+} -+ -+static inline size_t pvector_count(const struct pvector *pvec) -+{ -+ return ovsrcu_get(struct pvector_impl *, &pvec->impl)->size; -+} -+ -+static inline bool pvector_is_empty(const struct pvector *pvec) -+{ -+ return pvector_count(pvec) == 0; -+} -+ -+void pvector_publish__(struct pvector *); -+ -+/* Make the modified pvector available for iteration. */ -+static inline void pvector_publish(struct pvector *pvec) -+{ -+ if (pvec->temp) { -+ pvector_publish__(pvec); -+ } -+} -+ -+#endif /* pvector.h */ -Index: openvswitch-2.17.2/lib/rculist.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/rculist.h -+++ /dev/null -@@ -1,421 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --#ifndef RCULIST_H --#define RCULIST_H 1 -- --/* A single writer multiple RCU-reader doubly linked list. -- * -- * RCU readers may iterate over the list at the same time as a writer is -- * modifying the list. Multiple writers can be supported by use of mutual -- * exclusion, but rculist does not provide that, as the user of rculist -- * typically does that already. -- * -- * To be RCU-friendly, the struct rculist instances must be freed via -- * ovsrcu_postpone(). -- * -- * The API is almost the same as for struct ovs_list, with the following -- * exceptions: -- * -- * - The 'prev' pointer may not be accessed by the user. -- * - The 'next' pointer should be accessed via rculist_next() by readers, and -- * rculist_next_protected() by the writer. -- * - No rculist_moved(): due to the memory management limitation stated above, -- * rculist instances may not be reallocated, as realloc may instantly free -- * the old memory. -- * - rculist_front() returns a const pointer to accommodate for an RCU reader. -- * - rculist_splice_hidden(): Spliced elements may not have been visible to -- * RCU readers before the operation. -- * - rculist_poison(): Only poisons the 'prev' pointer. -- * -- * The following functions are variations of the struct ovs_list functions with -- * similar names, but are now restricted to the writer use: -- * -- * - rculist_back_protected() -- * - rculist_is_short_protected() -- * - rculist_is_singleton_protected() -- */ -- --#include --#include --#include "ovs-rcu.h" --#include "util.h" -- --/* A non-existing mutex to make it more difficult for an user to accidentally -- * keep using the 'prev' pointer. This may be helpful when porting code from -- * struct ovs_list to rculist. */ --extern struct ovs_mutex rculist_fake_mutex; -- --/* Doubly linked list head or element. */ --struct rculist { -- /* Previous list element. */ -- struct rculist *prev OVS_GUARDED_BY(rculist_fake_mutex); -- -- /* Next list element. */ -- OVSRCU_TYPE(struct rculist *) next; --}; -- --/* Easier access to 'next' member. */ --static inline const struct rculist *rculist_next(const struct rculist *); --static inline struct rculist *rculist_next_protected(const struct rculist *); -- --/* List initialization. */ --#define RCUOVS_LIST_INITIALIZER(LIST) { LIST, OVSRCU_INITIALIZER(LIST) } -- --static inline void rculist_init(struct rculist *list); --static inline void rculist_poison(struct rculist *elem); -- --/* List insertion. */ --static inline void rculist_insert(struct rculist *list, struct rculist *elem); --static inline void rculist_splice_hidden(struct rculist *before, -- struct rculist *first, -- struct rculist *last); --static inline void rculist_push_front(struct rculist *list, -- struct rculist *elem); --static inline void rculist_push_back(struct rculist *list, -- struct rculist *elem); --static inline void rculist_replace(struct rculist *replacement, -- struct rculist *replaced); --static inline void rculist_move(struct rculist *dst, struct rculist *src); -- --/* List removal. */ --static inline struct rculist *rculist_remove(struct rculist *elem); --static inline struct rculist *rculist_pop_front(struct rculist *list); --static inline struct rculist *rculist_pop_back(struct rculist *list); -- --/* List elements. */ --static inline const struct rculist *rculist_front(const struct rculist *); --static inline struct rculist *rculist_back_protected(const struct rculist *); -- --/* List properties. */ --static inline size_t rculist_size(const struct rculist *); --static inline bool rculist_is_empty(const struct rculist *); --static inline bool rculist_is_singleton_protected(const struct rculist *); --static inline bool rculist_is_short_protected(const struct rculist *); -- -- --/* Inline implementations. */ -- --static inline const struct rculist * --rculist_next(const struct rculist *list) --{ -- return ovsrcu_get(struct rculist *, &list->next); --} -- --static inline struct rculist * --rculist_next_protected(const struct rculist *list) -- --{ -- return ovsrcu_get_protected(struct rculist *, &list->next); --} -- --static inline void --rculist_init(struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- list->prev = list; -- ovsrcu_init(&list->next, list); --} -- --#define RCULIST_POISON (struct rculist *)(UINTPTR_MAX / 0xf * 0xc) -- --/* Initializes 'list' with pointers that will (probably) cause segfaults if -- * dereferenced and, better yet, show up clearly in a debugger. */ --static inline void --rculist_poison(struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- list->prev = RCULIST_POISON; --} -- --/* Initializes 'list' with pointers that will (probably) cause segfaults if -- * dereferenced and, better yet, show up clearly in a debugger. -- * -- * This variant poisons also the next pointer, so this may not be called if -- * this list element is still visible to RCU readers. */ --static inline void --rculist_poison__(struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- rculist_poison(list); -- ovsrcu_set_hidden(&list->next, RCULIST_POISON); --} -- --/* rculist insertion. */ --static inline void --rculist_insert(struct rculist *before, struct rculist *elem) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- elem->prev = before->prev; -- ovsrcu_set_hidden(&elem->next, before); -- ovsrcu_set(&before->prev->next, elem); -- before->prev = elem; --} -- --/* Removes elements 'first' though 'last' (exclusive) from their current list, -- * which may NOT be visible to any other threads (== be hidden from them), -- * then inserts them just before 'before'. */ --static inline void --rculist_splice_hidden(struct rculist *before, struct rculist *first, -- struct rculist *last) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- struct rculist *last_next; -- -- if (first == last) { -- return; -- } -- last = last->prev; -- -- /* Cleanly remove 'first'...'last' from its current list. */ -- last_next = rculist_next_protected(last); -- last_next->prev = first->prev; -- ovsrcu_set_hidden(&first->prev->next, last_next); -- -- /* Splice 'first'...'last' into new list. */ -- first->prev = before->prev; -- ovsrcu_set(&last->next, before); -- ovsrcu_set(&before->prev->next, first); -- before->prev = last; --} -- --/* Inserts 'elem' at the beginning of 'list', so that it becomes the front in -- * 'list'. */ --static inline void --rculist_push_front(struct rculist *list, struct rculist *elem) --{ -- rculist_insert(rculist_next_protected(list), elem); --} -- --/* Inserts 'elem' at the end of 'list', so that it becomes the back in -- * 'list'. */ --static inline void --rculist_push_back(struct rculist *list, struct rculist *elem) --{ -- rculist_insert(list, elem); --} -- --/* Puts 'element' in the position currently occupied by 'position'. -- * -- * Afterward, 'position' is not linked to from the list any more, but still -- * links to the nodes in the list, and may still be referenced by other threads -- * until all other threads quiesce. The replaced node ('position') may not be -- * re-inserted, re-initialized, or deleted until after all other threads have -- * quiesced (use ovsrcu_postpone). */ --static inline void --rculist_replace(struct rculist *element, struct rculist *position) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- struct rculist *position_next = rculist_next_protected(position); -- -- ovsrcu_set_hidden(&element->next, position_next); -- position_next->prev = element; -- element->prev = position->prev; -- ovsrcu_set(&element->prev->next, element); -- rculist_poison(position); --} -- --/* Initializes 'dst' with the contents of 'src', compensating for moving it -- * around in memory. The effect is that, if 'src' was the head of a list, now -- * 'dst' is the head of a list containing the same elements. -- * -- * Memory for 'src' must be kept around until the next RCU quiescent period. -- * rculist cannot be simply reallocated, so there is no rculist_moved(). */ --static inline void --rculist_move(struct rculist *dst, struct rculist *src) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- if (!rculist_is_empty(src)) { -- struct rculist *src_next = rculist_next_protected(src); -- -- dst->prev = src->prev; -- ovsrcu_set_hidden(&dst->next, src_next); -- -- src_next->prev = dst; -- ovsrcu_set(&src->prev->next, dst); -- } else { -- rculist_init(dst); -- } -- rculist_poison(src); --} -- --/* Removes 'elem' from its list and returns the element that followed it. -- * Has no effect when 'elem' is initialized, but not in a list. -- * Undefined behavior if 'elem' is not initialized. -- * -- * Afterward, 'elem' is not linked to from the list any more, but still links -- * to the nodes in the list, and may still be referenced by other threads until -- * all other threads quiesce. The removed node ('elem') may not be -- * re-inserted, re-initialized, or deleted until after all other threads have -- * quiesced (use ovsrcu_postpone). -- */ --static inline struct rculist * --rculist_remove(struct rculist *elem) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- struct rculist *elem_next = rculist_next_protected(elem); -- -- elem_next->prev = elem->prev; -- ovsrcu_set(&elem->prev->next, elem_next); -- rculist_poison(elem); -- return elem_next; --} -- --/* Removes the front element from 'list' and returns it. Undefined behavior if -- * 'list' is empty before removal. -- * -- * Afterward, teh returned former first node is not linked to from the list any -- * more, but still links to the nodes in the list, and may still be referenced -- * by other threads until all other threads quiesce. The returned node may not -- * be re-inserted, re-initialized, or deleted until after all other threads -- * have quiesced (use ovsrcu_postpone). */ --static inline struct rculist * --rculist_pop_front(struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- struct rculist *front = rculist_next_protected(list); -- rculist_remove(front); -- return front; --} -- --/* Removes the back element from 'list' and returns it. -- * Undefined behavior if 'list' is empty before removal. -- * -- * Afterward, teh returned former last node is not linked to from the list any -- * more, but still links to the nodes in the list, and may still be referenced -- * by other threads until all other threads quiesce. The returned node may not -- * be re-inserted, re-initialized, or deleted until after all other threads -- * have quiesced (use ovsrcu_postpone). */ --static inline struct rculist * --rculist_pop_back(struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- struct rculist *back = list->prev; -- rculist_remove(back); -- return back; --} -- --/* Returns the front element in 'list_'. -- * Undefined behavior if 'list_' is empty. */ --static inline const struct rculist * --rculist_front(const struct rculist *list) --{ -- ovs_assert(!rculist_is_empty(list)); -- -- return rculist_next(list); --} -- --/* Returns the back element in 'list_'. -- * Returns the 'list_' itself, if 'list_' is empty. */ --static inline struct rculist * --rculist_back_protected(const struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- return CONST_CAST(struct rculist *, list)->prev; --} -- --/* Returns the number of elements in 'list'. -- * Runs in O(n) in the number of elements. */ --static inline size_t --rculist_size(const struct rculist *list) --{ -- const struct rculist *e; -- size_t cnt = 0; -- -- for (e = rculist_next(list); e != list; e = rculist_next(e)) { -- cnt++; -- } -- return cnt; --} -- --/* Returns true if 'list' is empty, false otherwise. */ --static inline bool --rculist_is_empty(const struct rculist *list) --{ -- return rculist_next(list) == list; --} -- --/* Returns true if 'list' has 0 or 1 elements, false otherwise. */ --static inline bool --rculist_is_short_protected(const struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- return rculist_next_protected(list) == list->prev; --} -- --/* Returns true if 'list' has exactly 1 element, false otherwise. */ --static inline bool --rculist_is_singleton_protected(const struct rculist *list) -- OVS_NO_THREAD_SAFETY_ANALYSIS --{ -- const struct rculist *list_next = rculist_next_protected(list); -- -- return list_next == list->prev && list_next != list; --} -- --#define RCULIST_FOR_EACH(ITER, MEMBER, RCULIST) \ -- for (INIT_MULTIVAR(ITER, MEMBER, rculist_next(RCULIST), \ -- const struct rculist); \ -- CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -- UPDATE_MULTIVAR(ITER, rculist_next(ITER_VAR(ITER)))) -- --#define RCULIST_FOR_EACH_CONTINUE(ITER, MEMBER, RCULIST) \ -- for (INIT_MULTIVAR(ITER, MEMBER, rculist_next(&(ITER)->MEMBER), \ -- const struct rculist); \ -- CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -- UPDATE_MULTIVAR(ITER, rculist_next(ITER_VAR(ITER)))) -- --#define RCULIST_FOR_EACH_REVERSE_PROTECTED(ITER, MEMBER, RCULIST) \ -- for (INIT_MULTIVAR(ITER, MEMBER, (RCULIST)->prev, struct rculist); \ -- CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -- UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev)) -- --#define RCULIST_FOR_EACH_REVERSE_PROTECTED_CONTINUE(ITER, MEMBER, RCULIST) \ -- for (INIT_MULTIVAR(ITER, MEMBER, (ITER)->MEMBER.prev, struct rculist); \ -- CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -- UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev)) -- --#define RCULIST_FOR_EACH_PROTECTED(ITER, MEMBER, RCULIST) \ -- for (INIT_MULTIVAR(ITER, MEMBER, rculist_next_protected(RCULIST), \ -- struct rculist); \ -- CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -- UPDATE_MULTIVAR(ITER, rculist_next_protected(ITER_VAR(ITER))) \ -- --#define RCULIST_FOR_EACH_SAFE_SHORT_PROTECTED(ITER, MEMBER, RCULIST) \ -- for (INIT_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \ -- rculist_next_protected(RCULIST), \ -- struct rculist); \ -- CONDITION_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \ -- ITER_VAR(ITER) != (RCULIST), \ -- ITER_NEXT_VAR(ITER) = rculist_next_protected(ITER_VAR(VAR))); \ -- UPDATE_MULTIVAR_SHORT(ITER)) -- --#define RCULIST_FOR_EACH_SAFE_LONG_PROTECTED(ITER, NEXT, MEMBER, RCULIST) \ -- for (INIT_MULTIVAR_SAFE_LONG(ITER, NEXT, MEMBER, \ -- rculist_next_protected(RCULIST) \ -- struct rculist); \ -- CONDITION_MULTIVAR_SAFE_LONG(VAR, NEXT, MEMBER \ -- ITER_VAR(ITER) != (RCULIST), \ -- ITER_VAR(NEXT) = rculist_next_protected(ITER_VAR(VAR)), \ -- ITER_VAR(NEXT) != (RCULIST)); \ -- UPDATE_MULTIVAR_LONG(ITER)) -- --#define RCULIST_FOR_EACH_SAFE_PROTECTED(...) \ -- OVERLOAD_SAFE_MACRO(RCULIST_FOR_EACH_SAFE_LONG_PROTECTED, \ -- RCULIST_FOR_EACH_SAFE_SHORT_PROTECTED, \ -- 4, __VA_ARGS__) -- -- --#endif /* rculist.h */ -Index: openvswitch-2.17.2/include/internal/rculist.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/rculist.h -@@ -0,0 +1,421 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+#ifndef RCULIST_H -+#define RCULIST_H 1 -+ -+/* A single writer multiple RCU-reader doubly linked list. -+ * -+ * RCU readers may iterate over the list at the same time as a writer is -+ * modifying the list. Multiple writers can be supported by use of mutual -+ * exclusion, but rculist does not provide that, as the user of rculist -+ * typically does that already. -+ * -+ * To be RCU-friendly, the struct rculist instances must be freed via -+ * ovsrcu_postpone(). -+ * -+ * The API is almost the same as for struct ovs_list, with the following -+ * exceptions: -+ * -+ * - The 'prev' pointer may not be accessed by the user. -+ * - The 'next' pointer should be accessed via rculist_next() by readers, and -+ * rculist_next_protected() by the writer. -+ * - No rculist_moved(): due to the memory management limitation stated above, -+ * rculist instances may not be reallocated, as realloc may instantly free -+ * the old memory. -+ * - rculist_front() returns a const pointer to accommodate for an RCU reader. -+ * - rculist_splice_hidden(): Spliced elements may not have been visible to -+ * RCU readers before the operation. -+ * - rculist_poison(): Only poisons the 'prev' pointer. -+ * -+ * The following functions are variations of the struct ovs_list functions with -+ * similar names, but are now restricted to the writer use: -+ * -+ * - rculist_back_protected() -+ * - rculist_is_short_protected() -+ * - rculist_is_singleton_protected() -+ */ -+ -+#include -+#include -+#include "openvswitch/ovs-rcu.h" -+#include "internal/util.h" -+ -+/* A non-existing mutex to make it more difficult for an user to accidentally -+ * keep using the 'prev' pointer. This may be helpful when porting code from -+ * struct ovs_list to rculist. */ -+extern struct ovs_mutex rculist_fake_mutex; -+ -+/* Doubly linked list head or element. */ -+struct rculist { -+ /* Previous list element. */ -+ struct rculist *prev OVS_GUARDED_BY(rculist_fake_mutex); -+ -+ /* Next list element. */ -+ OVSRCU_TYPE(struct rculist *) next; -+}; -+ -+/* Easier access to 'next' member. */ -+static inline const struct rculist *rculist_next(const struct rculist *); -+static inline struct rculist *rculist_next_protected(const struct rculist *); -+ -+/* List initialization. */ -+#define RCUOVS_LIST_INITIALIZER(LIST) { LIST, OVSRCU_INITIALIZER(LIST) } -+ -+static inline void rculist_init(struct rculist *list); -+static inline void rculist_poison(struct rculist *elem); -+ -+/* List insertion. */ -+static inline void rculist_insert(struct rculist *list, struct rculist *elem); -+static inline void rculist_splice_hidden(struct rculist *before, -+ struct rculist *first, -+ struct rculist *last); -+static inline void rculist_push_front(struct rculist *list, -+ struct rculist *elem); -+static inline void rculist_push_back(struct rculist *list, -+ struct rculist *elem); -+static inline void rculist_replace(struct rculist *replacement, -+ struct rculist *replaced); -+static inline void rculist_move(struct rculist *dst, struct rculist *src); -+ -+/* List removal. */ -+static inline struct rculist *rculist_remove(struct rculist *elem); -+static inline struct rculist *rculist_pop_front(struct rculist *list); -+static inline struct rculist *rculist_pop_back(struct rculist *list); -+ -+/* List elements. */ -+static inline const struct rculist *rculist_front(const struct rculist *); -+static inline struct rculist *rculist_back_protected(const struct rculist *); -+ -+/* List properties. */ -+static inline size_t rculist_size(const struct rculist *); -+static inline bool rculist_is_empty(const struct rculist *); -+static inline bool rculist_is_singleton_protected(const struct rculist *); -+static inline bool rculist_is_short_protected(const struct rculist *); -+ -+ -+/* Inline implementations. */ -+ -+static inline const struct rculist * -+rculist_next(const struct rculist *list) -+{ -+ return ovsrcu_get(struct rculist *, &list->next); -+} -+ -+static inline struct rculist * -+rculist_next_protected(const struct rculist *list) -+ -+{ -+ return ovsrcu_get_protected(struct rculist *, &list->next); -+} -+ -+static inline void -+rculist_init(struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ list->prev = list; -+ ovsrcu_init(&list->next, list); -+} -+ -+#define RCULIST_POISON (struct rculist *)(UINTPTR_MAX / 0xf * 0xc) -+ -+/* Initializes 'list' with pointers that will (probably) cause segfaults if -+ * dereferenced and, better yet, show up clearly in a debugger. */ -+static inline void -+rculist_poison(struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ list->prev = RCULIST_POISON; -+} -+ -+/* Initializes 'list' with pointers that will (probably) cause segfaults if -+ * dereferenced and, better yet, show up clearly in a debugger. -+ * -+ * This variant poisons also the next pointer, so this may not be called if -+ * this list element is still visible to RCU readers. */ -+static inline void -+rculist_poison__(struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ rculist_poison(list); -+ ovsrcu_set_hidden(&list->next, RCULIST_POISON); -+} -+ -+/* rculist insertion. */ -+static inline void -+rculist_insert(struct rculist *before, struct rculist *elem) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ elem->prev = before->prev; -+ ovsrcu_set_hidden(&elem->next, before); -+ ovsrcu_set(&before->prev->next, elem); -+ before->prev = elem; -+} -+ -+/* Removes elements 'first' though 'last' (exclusive) from their current list, -+ * which may NOT be visible to any other threads (== be hidden from them), -+ * then inserts them just before 'before'. */ -+static inline void -+rculist_splice_hidden(struct rculist *before, struct rculist *first, -+ struct rculist *last) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ struct rculist *last_next; -+ -+ if (first == last) { -+ return; -+ } -+ last = last->prev; -+ -+ /* Cleanly remove 'first'...'last' from its current list. */ -+ last_next = rculist_next_protected(last); -+ last_next->prev = first->prev; -+ ovsrcu_set_hidden(&first->prev->next, last_next); -+ -+ /* Splice 'first'...'last' into new list. */ -+ first->prev = before->prev; -+ ovsrcu_set(&last->next, before); -+ ovsrcu_set(&before->prev->next, first); -+ before->prev = last; -+} -+ -+/* Inserts 'elem' at the beginning of 'list', so that it becomes the front in -+ * 'list'. */ -+static inline void -+rculist_push_front(struct rculist *list, struct rculist *elem) -+{ -+ rculist_insert(rculist_next_protected(list), elem); -+} -+ -+/* Inserts 'elem' at the end of 'list', so that it becomes the back in -+ * 'list'. */ -+static inline void -+rculist_push_back(struct rculist *list, struct rculist *elem) -+{ -+ rculist_insert(list, elem); -+} -+ -+/* Puts 'element' in the position currently occupied by 'position'. -+ * -+ * Afterward, 'position' is not linked to from the list any more, but still -+ * links to the nodes in the list, and may still be referenced by other threads -+ * until all other threads quiesce. The replaced node ('position') may not be -+ * re-inserted, re-initialized, or deleted until after all other threads have -+ * quiesced (use ovsrcu_postpone). */ -+static inline void -+rculist_replace(struct rculist *element, struct rculist *position) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ struct rculist *position_next = rculist_next_protected(position); -+ -+ ovsrcu_set_hidden(&element->next, position_next); -+ position_next->prev = element; -+ element->prev = position->prev; -+ ovsrcu_set(&element->prev->next, element); -+ rculist_poison(position); -+} -+ -+/* Initializes 'dst' with the contents of 'src', compensating for moving it -+ * around in memory. The effect is that, if 'src' was the head of a list, now -+ * 'dst' is the head of a list containing the same elements. -+ * -+ * Memory for 'src' must be kept around until the next RCU quiescent period. -+ * rculist cannot be simply reallocated, so there is no rculist_moved(). */ -+static inline void -+rculist_move(struct rculist *dst, struct rculist *src) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ if (!rculist_is_empty(src)) { -+ struct rculist *src_next = rculist_next_protected(src); -+ -+ dst->prev = src->prev; -+ ovsrcu_set_hidden(&dst->next, src_next); -+ -+ src_next->prev = dst; -+ ovsrcu_set(&src->prev->next, dst); -+ } else { -+ rculist_init(dst); -+ } -+ rculist_poison(src); -+} -+ -+/* Removes 'elem' from its list and returns the element that followed it. -+ * Has no effect when 'elem' is initialized, but not in a list. -+ * Undefined behavior if 'elem' is not initialized. -+ * -+ * Afterward, 'elem' is not linked to from the list any more, but still links -+ * to the nodes in the list, and may still be referenced by other threads until -+ * all other threads quiesce. The removed node ('elem') may not be -+ * re-inserted, re-initialized, or deleted until after all other threads have -+ * quiesced (use ovsrcu_postpone). -+ */ -+static inline struct rculist * -+rculist_remove(struct rculist *elem) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ struct rculist *elem_next = rculist_next_protected(elem); -+ -+ elem_next->prev = elem->prev; -+ ovsrcu_set(&elem->prev->next, elem_next); -+ rculist_poison(elem); -+ return elem_next; -+} -+ -+/* Removes the front element from 'list' and returns it. Undefined behavior if -+ * 'list' is empty before removal. -+ * -+ * Afterward, teh returned former first node is not linked to from the list any -+ * more, but still links to the nodes in the list, and may still be referenced -+ * by other threads until all other threads quiesce. The returned node may not -+ * be re-inserted, re-initialized, or deleted until after all other threads -+ * have quiesced (use ovsrcu_postpone). */ -+static inline struct rculist * -+rculist_pop_front(struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ struct rculist *front = rculist_next_protected(list); -+ rculist_remove(front); -+ return front; -+} -+ -+/* Removes the back element from 'list' and returns it. -+ * Undefined behavior if 'list' is empty before removal. -+ * -+ * Afterward, teh returned former last node is not linked to from the list any -+ * more, but still links to the nodes in the list, and may still be referenced -+ * by other threads until all other threads quiesce. The returned node may not -+ * be re-inserted, re-initialized, or deleted until after all other threads -+ * have quiesced (use ovsrcu_postpone). */ -+static inline struct rculist * -+rculist_pop_back(struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ struct rculist *back = list->prev; -+ rculist_remove(back); -+ return back; -+} -+ -+/* Returns the front element in 'list_'. -+ * Undefined behavior if 'list_' is empty. */ -+static inline const struct rculist * -+rculist_front(const struct rculist *list) -+{ -+ ovs_assert(!rculist_is_empty(list)); -+ -+ return rculist_next(list); -+} -+ -+/* Returns the back element in 'list_'. -+ * Returns the 'list_' itself, if 'list_' is empty. */ -+static inline struct rculist * -+rculist_back_protected(const struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ return CONST_CAST(struct rculist *, list)->prev; -+} -+ -+/* Returns the number of elements in 'list'. -+ * Runs in O(n) in the number of elements. */ -+static inline size_t -+rculist_size(const struct rculist *list) -+{ -+ const struct rculist *e; -+ size_t cnt = 0; -+ -+ for (e = rculist_next(list); e != list; e = rculist_next(e)) { -+ cnt++; -+ } -+ return cnt; -+} -+ -+/* Returns true if 'list' is empty, false otherwise. */ -+static inline bool -+rculist_is_empty(const struct rculist *list) -+{ -+ return rculist_next(list) == list; -+} -+ -+/* Returns true if 'list' has 0 or 1 elements, false otherwise. */ -+static inline bool -+rculist_is_short_protected(const struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ return rculist_next_protected(list) == list->prev; -+} -+ -+/* Returns true if 'list' has exactly 1 element, false otherwise. */ -+static inline bool -+rculist_is_singleton_protected(const struct rculist *list) -+ OVS_NO_THREAD_SAFETY_ANALYSIS -+{ -+ const struct rculist *list_next = rculist_next_protected(list); -+ -+ return list_next == list->prev && list_next != list; -+} -+ -+#define RCULIST_FOR_EACH(ITER, MEMBER, RCULIST) \ -+ for (INIT_MULTIVAR(ITER, MEMBER, rculist_next(RCULIST), \ -+ const struct rculist); \ -+ CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, rculist_next(ITER_VAR(ITER)))) -+ -+#define RCULIST_FOR_EACH_CONTINUE(ITER, MEMBER, RCULIST) \ -+ for (INIT_MULTIVAR(ITER, MEMBER, rculist_next(&(ITER)->MEMBER), \ -+ const struct rculist); \ -+ CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, rculist_next(ITER_VAR(ITER)))) -+ -+#define RCULIST_FOR_EACH_REVERSE_PROTECTED(ITER, MEMBER, RCULIST) \ -+ for (INIT_MULTIVAR(ITER, MEMBER, (RCULIST)->prev, struct rculist); \ -+ CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev)) -+ -+#define RCULIST_FOR_EACH_REVERSE_PROTECTED_CONTINUE(ITER, MEMBER, RCULIST) \ -+ for (INIT_MULTIVAR(ITER, MEMBER, (ITER)->MEMBER.prev, struct rculist); \ -+ CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, ITER_VAR(VAR).prev)) -+ -+#define RCULIST_FOR_EACH_PROTECTED(ITER, MEMBER, RCULIST) \ -+ for (INIT_MULTIVAR(ITER, MEMBER, rculist_next_protected(RCULIST), \ -+ struct rculist); \ -+ CONDITION_MULTIVAR(ITER, MEMBER, ITER_VAR(ITER) != (RCULIST)); \ -+ UPDATE_MULTIVAR(ITER, rculist_next_protected(ITER_VAR(ITER))) \ -+ -+#define RCULIST_FOR_EACH_SAFE_SHORT_PROTECTED(ITER, MEMBER, RCULIST) \ -+ for (INIT_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \ -+ rculist_next_protected(RCULIST), \ -+ struct rculist); \ -+ CONDITION_MULTIVAR_SAFE_SHORT(ITER, MEMBER, \ -+ ITER_VAR(ITER) != (RCULIST), \ -+ ITER_NEXT_VAR(ITER) = rculist_next_protected(ITER_VAR(VAR))); \ -+ UPDATE_MULTIVAR_SHORT(ITER)) -+ -+#define RCULIST_FOR_EACH_SAFE_LONG_PROTECTED(ITER, NEXT, MEMBER, RCULIST) \ -+ for (INIT_MULTIVAR_SAFE_LONG(ITER, NEXT, MEMBER, \ -+ rculist_next_protected(RCULIST) \ -+ struct rculist); \ -+ CONDITION_MULTIVAR_SAFE_LONG(VAR, NEXT, MEMBER \ -+ ITER_VAR(ITER) != (RCULIST), \ -+ ITER_VAR(NEXT) = rculist_next_protected(ITER_VAR(VAR)), \ -+ ITER_VAR(NEXT) != (RCULIST)); \ -+ UPDATE_MULTIVAR_LONG(ITER)) -+ -+#define RCULIST_FOR_EACH_SAFE_PROTECTED(...) \ -+ OVERLOAD_SAFE_MACRO(RCULIST_FOR_EACH_SAFE_LONG_PROTECTED, \ -+ RCULIST_FOR_EACH_SAFE_SHORT_PROTECTED, \ -+ 4, __VA_ARGS__) -+ -+ -+#endif /* rculist.h */ -Index: openvswitch-2.17.2/lib/seq.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/seq.h -+++ /dev/null -@@ -1,139 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef SEQ_H --#define SEQ_H 1 -- --/* Thread-safe, pollable sequence number. -- * -- * -- * Motivation -- * ========== -- * -- * It is sometimes desirable to take an action whenever an object changes. -- * Suppose we associate a sequence number with an object and increment the -- * sequence number whenver we change the object. An observer can then record -- * the sequence number it sees. Later on, if the current sequence number -- * differs from the one it saw last, then the observer knows to examine the -- * object for changes. -- * -- * Code that wants to run when a sequence number changes is challenging to -- * implement in a multithreaded environment. A naive implementation, that -- * simply checks whether the sequence number changed and, if so, calls -- * poll_immediate_wake(), will fail when another thread increments the sequence -- * number after the check (including during poll_block()). -- * -- * struct seq is a solution. It implements a sequence number along with enough -- * internal infrastructure so that a thread waiting on a particular value will -- * wake up if the sequence number changes, or even if the "struct seq" is -- * destroyed. -- * -- * -- * Usage -- * ===== -- * -- * The object that includes a sequence number should use seq_create() and -- * seq_destroy() at creation and destruction, and seq_change() whenever the -- * object's observable state changes. -- * -- * An observer may seq_read() to read the current sequence number and -- * seq_wait() to cause poll_block() to wake up when the sequence number changes -- * from a specified value. -- * -- * To avoid races, observers should use seq_read() to check for changes, -- * process any changes, and then use seq_wait() to wait for a change from the -- * previously read value. That is, a correct usage looks something like this: -- * -- * new_seq = seq_read(seq); -- * if (new_seq != last_seq) { -- * ...process changes... -- * last_seq = new_seq; -- * } -- * seq_wait(seq, new_seq); -- * poll_block(); -- * -- * -- * Alternate Usage -- * =============== -- * -- * struct seq can also be used as a sort of pollable condition variable. -- * Suppose that we want a thread to process items in a queue, and thus to be -- * able to wake up whenever the queue is nonempty. This requires a lock to -- * protect the queue and a seq to signal that the queue has become nonempty, -- * e.g.: -- * -- * struct ovs_mutex mutex; -- * struct ovs_list queue OVS_GUARDED_BY(mutex); -- * struct seq *nonempty_seq; -- * -- * To add an element to the queue: -- * -- * ovs_mutex_lock(&mutex); -- * ovs_list_push_back(&queue, ...element...); -- * if (ovs_list_is_singleton(&queue)) { <-- The 'if' here is optional. -- * seq_change(nonempty_seq); -- * } -- * ovs_mutex_unlock(&mutex); -- * -- * To wait for the queue to become nonempty: -- * -- * ovs_mutex_lock(&mutex); -- * if (ovs_list_is_empty(&queue)) { -- * seq_wait(nonempty_seq, seq_read(nonempty_seq)); -- * } else { -- * poll_immediate_wake(); -- * } -- * ovs_mutex_unlock(&mutex); -- * -- * (In the above code 'mutex' prevents the queue from changing between -- * seq_read() and seq_wait(). Otherwise, it would be necessary to seq_read(), -- * check for a nonempty queue, and then seq_wait() on the previously read -- * sequence number, as under Usage above.) -- * -- * -- * Thread-safety -- * ============= -- * -- * Fully thread safe. seq_change() synchronizes with seq_read() and -- * seq_wait() on the same variable in release-acquire fashion. That -- * is, all effects of the memory accesses performed by a thread prior -- * to seq_change() are visible to the threads returning from -- * seq_read() or seq_wait() observing that change. -- */ -- --#include --#include "util.h" -- --/* For implementation of an object with a sequence number attached. */ --struct seq *seq_create(void); --void seq_destroy(struct seq *); --void seq_change(struct seq *); --void seq_change_protected(struct seq *); --void seq_lock(void); --int seq_try_lock(void); --void seq_unlock(void); -- --/* For observers. */ --uint64_t seq_read(const struct seq *); --uint64_t seq_read_protected(const struct seq *); -- --void seq_wait_at(const struct seq *, uint64_t value, const char *where); --#define seq_wait(seq, value) seq_wait_at(seq, value, OVS_SOURCE_LOCATOR) -- --/* For poll_block() internal use. */ --void seq_woke(void); -- --#endif /* seq.h */ -Index: openvswitch-2.17.2/include/internal/seq.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/seq.h -@@ -0,0 +1,139 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef SEQ_H -+#define SEQ_H 1 -+ -+/* Thread-safe, pollable sequence number. -+ * -+ * -+ * Motivation -+ * ========== -+ * -+ * It is sometimes desirable to take an action whenever an object changes. -+ * Suppose we associate a sequence number with an object and increment the -+ * sequence number whenver we change the object. An observer can then record -+ * the sequence number it sees. Later on, if the current sequence number -+ * differs from the one it saw last, then the observer knows to examine the -+ * object for changes. -+ * -+ * Code that wants to run when a sequence number changes is challenging to -+ * implement in a multithreaded environment. A naive implementation, that -+ * simply checks whether the sequence number changed and, if so, calls -+ * poll_immediate_wake(), will fail when another thread increments the sequence -+ * number after the check (including during poll_block()). -+ * -+ * struct seq is a solution. It implements a sequence number along with enough -+ * internal infrastructure so that a thread waiting on a particular value will -+ * wake up if the sequence number changes, or even if the "struct seq" is -+ * destroyed. -+ * -+ * -+ * Usage -+ * ===== -+ * -+ * The object that includes a sequence number should use seq_create() and -+ * seq_destroy() at creation and destruction, and seq_change() whenever the -+ * object's observable state changes. -+ * -+ * An observer may seq_read() to read the current sequence number and -+ * seq_wait() to cause poll_block() to wake up when the sequence number changes -+ * from a specified value. -+ * -+ * To avoid races, observers should use seq_read() to check for changes, -+ * process any changes, and then use seq_wait() to wait for a change from the -+ * previously read value. That is, a correct usage looks something like this: -+ * -+ * new_seq = seq_read(seq); -+ * if (new_seq != last_seq) { -+ * ...process changes... -+ * last_seq = new_seq; -+ * } -+ * seq_wait(seq, new_seq); -+ * poll_block(); -+ * -+ * -+ * Alternate Usage -+ * =============== -+ * -+ * struct seq can also be used as a sort of pollable condition variable. -+ * Suppose that we want a thread to process items in a queue, and thus to be -+ * able to wake up whenever the queue is nonempty. This requires a lock to -+ * protect the queue and a seq to signal that the queue has become nonempty, -+ * e.g.: -+ * -+ * struct ovs_mutex mutex; -+ * struct ovs_list queue OVS_GUARDED_BY(mutex); -+ * struct seq *nonempty_seq; -+ * -+ * To add an element to the queue: -+ * -+ * ovs_mutex_lock(&mutex); -+ * ovs_list_push_back(&queue, ...element...); -+ * if (ovs_list_is_singleton(&queue)) { <-- The 'if' here is optional. -+ * seq_change(nonempty_seq); -+ * } -+ * ovs_mutex_unlock(&mutex); -+ * -+ * To wait for the queue to become nonempty: -+ * -+ * ovs_mutex_lock(&mutex); -+ * if (ovs_list_is_empty(&queue)) { -+ * seq_wait(nonempty_seq, seq_read(nonempty_seq)); -+ * } else { -+ * poll_immediate_wake(); -+ * } -+ * ovs_mutex_unlock(&mutex); -+ * -+ * (In the above code 'mutex' prevents the queue from changing between -+ * seq_read() and seq_wait(). Otherwise, it would be necessary to seq_read(), -+ * check for a nonempty queue, and then seq_wait() on the previously read -+ * sequence number, as under Usage above.) -+ * -+ * -+ * Thread-safety -+ * ============= -+ * -+ * Fully thread safe. seq_change() synchronizes with seq_read() and -+ * seq_wait() on the same variable in release-acquire fashion. That -+ * is, all effects of the memory accesses performed by a thread prior -+ * to seq_change() are visible to the threads returning from -+ * seq_read() or seq_wait() observing that change. -+ */ -+ -+#include -+#include "internal/util.h" -+ -+/* For implementation of an object with a sequence number attached. */ -+struct seq *seq_create(void); -+void seq_destroy(struct seq *); -+void seq_change(struct seq *); -+void seq_change_protected(struct seq *); -+void seq_lock(void); -+int seq_try_lock(void); -+void seq_unlock(void); -+ -+/* For observers. */ -+uint64_t seq_read(const struct seq *); -+uint64_t seq_read_protected(const struct seq *); -+ -+void seq_wait_at(const struct seq *, uint64_t value, const char *where); -+#define seq_wait(seq, value) seq_wait_at(seq, value, OVS_SOURCE_LOCATOR) -+ -+/* For poll_block() internal use. */ -+void seq_woke(void); -+ -+#endif /* seq.h */ -Index: openvswitch-2.17.2/lib/smap.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/smap.h -+++ /dev/null -@@ -1,139 +0,0 @@ --/* Copyright (c) 2012, 2014, 2015, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. */ -- --#ifndef SMAP_H --#define SMAP_H 1 -- --#include --#include --#include "hash.h" --#include "openvswitch/hmap.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --struct json; --struct uuid; -- --/* A map from string to string. */ --struct smap { -- struct hmap map; /* Contains "struct smap_node"s. */ --}; -- --struct smap_node { -- struct hmap_node node; /* In struct smap's 'map' hmap. */ -- char *key; -- char *value; --}; -- --#define SMAP_INITIALIZER(SMAP) { HMAP_INITIALIZER(&(SMAP)->map) } -- --#define SMAP_FOR_EACH(SMAP_NODE, SMAP) \ -- HMAP_FOR_EACH_INIT (SMAP_NODE, node, &(SMAP)->map, \ -- BUILD_ASSERT_TYPE(SMAP_NODE, struct smap_node *), \ -- BUILD_ASSERT_TYPE(SMAP, struct smap *)) -- --#define SMAP_FOR_EACH_SAFE_SHORT(SMAP_NODE, SMAP) \ -- HMAP_FOR_EACH_SAFE_SHORT_INIT ( \ -- SMAP_NODE, node, &(SMAP)->map, \ -- BUILD_ASSERT_TYPE(SMAP_NODE, struct smap_node *), \ -- BUILD_ASSERT_TYPE(SMAP, struct smap *)) -- --#define SMAP_FOR_EACH_SAFE_LONG(SMAP_NODE, NEXT, SMAP) \ -- HMAP_FOR_EACH_SAFE_LONG_INIT ( \ -- SMAP_NODE, NEXT, node, &(SMAP)->map, \ -- BUILD_ASSERT_TYPE(SMAP_NODE, struct smap_node *), \ -- BUILD_ASSERT_TYPE(NEXT, struct smap_node *), \ -- BUILD_ASSERT_TYPE(SMAP, struct smap *)) -- --#define SMAP_FOR_EACH_SAFE(...) \ -- OVERLOAD_SAFE_MACRO(SMAP_FOR_EACH_SAFE_LONG, \ -- SMAP_FOR_EACH_SAFE_SHORT, \ -- 3, __VA_ARGS__) -- --/* Initializer for an immutable struct smap 'SMAP' that contains one or two -- * key-value pairs, e.g. -- * -- * const struct smap smap1 = SMAP_CONST1(&smap, "key", "value"); -- * const struct smap smap2 = SMAP_CONST2(&smap, "key1", "value1", -- * "key2", "value2"); -- * -- * An smap initialized this way must not be modified or destroyed. -- * -- * The 'KEY', 'K1', 'K2' arguments are evaluated multiple times. -- */ --#define SMAP_CONST1(SMAP, KEY, VALUE) (const struct smap) { \ -- HMAP_CONST(&(SMAP)->map, 1, SMAP_NODE(KEY, VALUE, NULL)) \ -- } --#define SMAP_CONST2(SMAP, K1, V1, K2, V2) (const struct smap) { \ -- HMAP_CONST(&(SMAP)->map, 2, \ -- SMAP_NODE(K1, V1, SMAP_NODE(K2, V2, NULL))) \ -- } --#define SMAP_NODE(KEY, VALUE, NEXT) \ -- &(struct smap_node) { \ -- .node = { \ -- .hash = hash_string(KEY, 0), \ -- .next = (NEXT), \ -- }, \ -- .key = CONST_CAST(char *, KEY), \ -- .value = CONST_CAST(char *, VALUE), \ -- }.node -- -- --void smap_init(struct smap *); --void smap_destroy(struct smap *); -- --struct smap_node *smap_add(struct smap *, const char *, const char *); --struct smap_node *smap_add_nocopy(struct smap *, char *, char *); --bool smap_add_once(struct smap *, const char *, const char *); --void smap_add_format(struct smap *, const char *key, const char *, ...) -- OVS_PRINTF_FORMAT(3, 4); --void smap_add_ipv6(struct smap *, const char *, struct in6_addr *); --void smap_replace(struct smap *, const char *, const char *); --void smap_replace_nocopy(struct smap *, const char *, char *); -- --void smap_remove(struct smap *, const char *); --void smap_remove_node(struct smap *, struct smap_node *); --void smap_steal(struct smap *, struct smap_node *, char **keyp, char **valuep); --void smap_clear(struct smap *); -- --const char *smap_get(const struct smap *, const char *key); --const char *smap_get_def(const struct smap *, const char *key, -- const char *def); --struct smap_node *smap_get_node(const struct smap *, const char *); --bool smap_get_bool(const struct smap *smap, const char *key, bool def); --int smap_get_int(const struct smap *smap, const char *key, int def); --unsigned int smap_get_uint(const struct smap *smap, const char *key, -- unsigned int def); --unsigned long long int smap_get_ullong(const struct smap *, const char *key, -- unsigned long long def); --bool smap_get_uuid(const struct smap *, const char *key, struct uuid *); -- --bool smap_is_empty(const struct smap *); --size_t smap_count(const struct smap *); -- --void smap_clone(struct smap *dst, const struct smap *src); --const struct smap_node **smap_sort(const struct smap *); -- --void smap_from_json(struct smap *, const struct json *); --struct json *smap_to_json(const struct smap *); -- --bool smap_equal(const struct smap *, const struct smap *); -- --#ifdef __cplusplus --} --#endif -- --#endif /* smap.h */ -Index: openvswitch-2.17.2/include/internal/smap.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/smap.h -@@ -0,0 +1,139 @@ -+/* Copyright (c) 2012, 2014, 2015, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. */ -+ -+#ifndef SMAP_H -+#define SMAP_H 1 -+ -+#include -+#include -+#include "internal/hash.h" -+#include "openvswitch/hmap.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct json; -+struct uuid; -+ -+/* A map from string to string. */ -+struct smap { -+ struct hmap map; /* Contains "struct smap_node"s. */ -+}; -+ -+struct smap_node { -+ struct hmap_node node; /* In struct smap's 'map' hmap. */ -+ char *key; -+ char *value; -+}; -+ -+#define SMAP_INITIALIZER(SMAP) { HMAP_INITIALIZER(&(SMAP)->map) } -+ -+#define SMAP_FOR_EACH(SMAP_NODE, SMAP) \ -+ HMAP_FOR_EACH_INIT (SMAP_NODE, node, &(SMAP)->map, \ -+ BUILD_ASSERT_TYPE(SMAP_NODE, struct smap_node *), \ -+ BUILD_ASSERT_TYPE(SMAP, struct smap *)) -+ -+#define SMAP_FOR_EACH_SAFE_SHORT(SMAP_NODE, SMAP) \ -+ HMAP_FOR_EACH_SAFE_SHORT_INIT ( \ -+ SMAP_NODE, node, &(SMAP)->map, \ -+ BUILD_ASSERT_TYPE(SMAP_NODE, struct smap_node *), \ -+ BUILD_ASSERT_TYPE(SMAP, struct smap *)) -+ -+#define SMAP_FOR_EACH_SAFE_LONG(SMAP_NODE, NEXT, SMAP) \ -+ HMAP_FOR_EACH_SAFE_LONG_INIT ( \ -+ SMAP_NODE, NEXT, node, &(SMAP)->map, \ -+ BUILD_ASSERT_TYPE(SMAP_NODE, struct smap_node *), \ -+ BUILD_ASSERT_TYPE(NEXT, struct smap_node *), \ -+ BUILD_ASSERT_TYPE(SMAP, struct smap *)) -+ -+#define SMAP_FOR_EACH_SAFE(...) \ -+ OVERLOAD_SAFE_MACRO(SMAP_FOR_EACH_SAFE_LONG, \ -+ SMAP_FOR_EACH_SAFE_SHORT, \ -+ 3, __VA_ARGS__) -+ -+/* Initializer for an immutable struct smap 'SMAP' that contains one or two -+ * key-value pairs, e.g. -+ * -+ * const struct smap smap1 = SMAP_CONST1(&smap, "key", "value"); -+ * const struct smap smap2 = SMAP_CONST2(&smap, "key1", "value1", -+ * "key2", "value2"); -+ * -+ * An smap initialized this way must not be modified or destroyed. -+ * -+ * The 'KEY', 'K1', 'K2' arguments are evaluated multiple times. -+ */ -+#define SMAP_CONST1(SMAP, KEY, VALUE) (const struct smap) { \ -+ HMAP_CONST(&(SMAP)->map, 1, SMAP_NODE(KEY, VALUE, NULL)) \ -+ } -+#define SMAP_CONST2(SMAP, K1, V1, K2, V2) (const struct smap) { \ -+ HMAP_CONST(&(SMAP)->map, 2, \ -+ SMAP_NODE(K1, V1, SMAP_NODE(K2, V2, NULL))) \ -+ } -+#define SMAP_NODE(KEY, VALUE, NEXT) \ -+ &(struct smap_node) { \ -+ .node = { \ -+ .hash = hash_string(KEY, 0), \ -+ .next = (NEXT), \ -+ }, \ -+ .key = CONST_CAST(char *, KEY), \ -+ .value = CONST_CAST(char *, VALUE), \ -+ }.node -+ -+ -+void smap_init(struct smap *); -+void smap_destroy(struct smap *); -+ -+struct smap_node *smap_add(struct smap *, const char *, const char *); -+struct smap_node *smap_add_nocopy(struct smap *, char *, char *); -+bool smap_add_once(struct smap *, const char *, const char *); -+void smap_add_format(struct smap *, const char *key, const char *, ...) -+ OVS_PRINTF_FORMAT(3, 4); -+void smap_add_ipv6(struct smap *, const char *, struct in6_addr *); -+void smap_replace(struct smap *, const char *, const char *); -+void smap_replace_nocopy(struct smap *, const char *, char *); -+ -+void smap_remove(struct smap *, const char *); -+void smap_remove_node(struct smap *, struct smap_node *); -+void smap_steal(struct smap *, struct smap_node *, char **keyp, char **valuep); -+void smap_clear(struct smap *); -+ -+const char *smap_get(const struct smap *, const char *key); -+const char *smap_get_def(const struct smap *, const char *key, -+ const char *def); -+struct smap_node *smap_get_node(const struct smap *, const char *); -+bool smap_get_bool(const struct smap *smap, const char *key, bool def); -+int smap_get_int(const struct smap *smap, const char *key, int def); -+unsigned int smap_get_uint(const struct smap *smap, const char *key, -+ unsigned int def); -+unsigned long long int smap_get_ullong(const struct smap *, const char *key, -+ unsigned long long def); -+bool smap_get_uuid(const struct smap *, const char *key, struct uuid *); -+ -+bool smap_is_empty(const struct smap *); -+size_t smap_count(const struct smap *); -+ -+void smap_clone(struct smap *dst, const struct smap *src); -+const struct smap_node **smap_sort(const struct smap *); -+ -+void smap_from_json(struct smap *, const struct json *); -+struct json *smap_to_json(const struct smap *); -+ -+bool smap_equal(const struct smap *, const struct smap *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* smap.h */ -Index: openvswitch-2.17.2/lib/sset.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/sset.h -+++ /dev/null -@@ -1,134 +0,0 @@ --/* -- * Copyright (c) 2011, 2012, 2013, 2015, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef SSET_H --#define SSET_H -- --#include "openvswitch/hmap.h" --#include "util.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --struct sset_node { -- struct hmap_node hmap_node; -- char name[1]; --}; -- --/* A set of strings. */ --struct sset { -- struct hmap map; --}; -- --#define SSET_INITIALIZER(SSET) { HMAP_INITIALIZER(&(SSET)->map) } -- --/* Basics. */ --void sset_init(struct sset *); --void sset_destroy(struct sset *); --void sset_clone(struct sset *, const struct sset *); --void sset_swap(struct sset *, struct sset *); --void sset_moved(struct sset *); -- --/* String parsing and formatting. */ --void sset_from_delimited_string(struct sset *, const char *s, -- const char *delimiters); --char *sset_join(const struct sset *, -- const char *delimiter, const char *terminator); -- --/* Count. */ --bool sset_is_empty(const struct sset *); --size_t sset_count(const struct sset *); -- --/* Insertion. */ --struct sset_node *sset_add(struct sset *, const char *); --struct sset_node *sset_add_and_free(struct sset *, char *); --void sset_add_assert(struct sset *, const char *); --void sset_add_array(struct sset *, char **, size_t n); -- --/* Deletion. */ --void sset_clear(struct sset *); --void sset_delete(struct sset *, struct sset_node *); --bool sset_find_and_delete(struct sset *, const char *); --void sset_find_and_delete_assert(struct sset *, const char *); --char *sset_pop(struct sset *); -- --/* Search. */ --struct sset_node *sset_find(const struct sset *, const char *); --bool sset_contains(const struct sset *, const char *); --bool sset_equals(const struct sset *, const struct sset *); -- --struct sset_position { -- struct hmap_position pos; --}; -- --struct sset_node *sset_at_position(const struct sset *, -- struct sset_position *); -- --/* Set operations. */ --void sset_intersect(struct sset *, const struct sset *); -- --/* Iteration macros. */ --#define SSET_FOR_EACH(NAME, SSET) \ -- for ((NAME) = SSET_FIRST(SSET); \ -- NAME != NULL; \ -- (NAME) = SSET_NEXT(SSET, NAME)) -- --#define SSET_FOR_EACH_SAFE_LONG(NAME, NEXT, SSET) \ -- for ((NAME) = SSET_FIRST(SSET); \ -- (NAME != NULL \ -- ? (NEXT) = SSET_NEXT(SSET, NAME), true \ -- : false); \ -- (NAME) = (NEXT)) -- --#define SSET_FOR_EACH_SAFE_SHORT(NAME, SSET) \ -- for (const char * NAME__next = \ -- ((NAME) = SSET_FIRST(SSET), NULL); \ -- (NAME != NULL \ -- ? (NAME__next = SSET_NEXT(SSET, NAME), true) \ -- : (NAME__next = NULL, false)); \ -- (NAME) = NAME__next) -- --#define SSET_FOR_EACH_SAFE(...) \ -- OVERLOAD_SAFE_MACRO(SSET_FOR_EACH_SAFE_LONG, \ -- SSET_FOR_EACH_SAFE_SHORT, \ -- 3, __VA_ARGS__) -- --const char **sset_array(const struct sset *); --const char **sset_sort(const struct sset *); -- --/* Implementation helper macros. */ -- --#define SSET_NODE_FROM_HMAP_NODE(HMAP_NODE) \ -- CONTAINER_OF(HMAP_NODE, struct sset_node, hmap_node) --#define SSET_NAME_FROM_HMAP_NODE(HMAP_NODE) \ -- HMAP_NODE == NULL \ -- ? NULL \ -- : (CONST_CAST(const char *, (SSET_NODE_FROM_HMAP_NODE(HMAP_NODE)->name))) --#define SSET_NODE_FROM_NAME(NAME) CONTAINER_OF(NAME, struct sset_node, name) --#define SSET_FIRST(SSET) \ -- (BUILD_ASSERT_TYPE(SSET, struct sset *), \ -- SSET_NAME_FROM_HMAP_NODE(hmap_first(&(SSET)->map))) --#define SSET_NEXT(SSET, NAME) \ -- (BUILD_ASSERT_TYPE(SSET, struct sset *), \ -- SSET_NAME_FROM_HMAP_NODE( \ -- hmap_next(&(SSET)->map, &SSET_NODE_FROM_NAME(NAME)->hmap_node))) -- --#ifdef __cplusplus --} --#endif -- --#endif /* sset.h */ -Index: openvswitch-2.17.2/include/internal/sset.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/sset.h -@@ -0,0 +1,134 @@ -+/* -+ * Copyright (c) 2011, 2012, 2013, 2015, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef SSET_H -+#define SSET_H -+ -+#include "openvswitch/hmap.h" -+#include "internal/util.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct sset_node { -+ struct hmap_node hmap_node; -+ char name[1]; -+}; -+ -+/* A set of strings. */ -+struct sset { -+ struct hmap map; -+}; -+ -+#define SSET_INITIALIZER(SSET) { HMAP_INITIALIZER(&(SSET)->map) } -+ -+/* Basics. */ -+void sset_init(struct sset *); -+void sset_destroy(struct sset *); -+void sset_clone(struct sset *, const struct sset *); -+void sset_swap(struct sset *, struct sset *); -+void sset_moved(struct sset *); -+ -+/* String parsing and formatting. */ -+void sset_from_delimited_string(struct sset *, const char *s, -+ const char *delimiters); -+char *sset_join(const struct sset *, -+ const char *delimiter, const char *terminator); -+ -+/* Count. */ -+bool sset_is_empty(const struct sset *); -+size_t sset_count(const struct sset *); -+ -+/* Insertion. */ -+struct sset_node *sset_add(struct sset *, const char *); -+struct sset_node *sset_add_and_free(struct sset *, char *); -+void sset_add_assert(struct sset *, const char *); -+void sset_add_array(struct sset *, char **, size_t n); -+ -+/* Deletion. */ -+void sset_clear(struct sset *); -+void sset_delete(struct sset *, struct sset_node *); -+bool sset_find_and_delete(struct sset *, const char *); -+void sset_find_and_delete_assert(struct sset *, const char *); -+char *sset_pop(struct sset *); -+ -+/* Search. */ -+struct sset_node *sset_find(const struct sset *, const char *); -+bool sset_contains(const struct sset *, const char *); -+bool sset_equals(const struct sset *, const struct sset *); -+ -+struct sset_position { -+ struct hmap_position pos; -+}; -+ -+struct sset_node *sset_at_position(const struct sset *, -+ struct sset_position *); -+ -+/* Set operations. */ -+void sset_intersect(struct sset *, const struct sset *); -+ -+/* Iteration macros. */ -+#define SSET_FOR_EACH(NAME, SSET) \ -+ for ((NAME) = SSET_FIRST(SSET); \ -+ NAME != NULL; \ -+ (NAME) = SSET_NEXT(SSET, NAME)) -+ -+#define SSET_FOR_EACH_SAFE_LONG(NAME, NEXT, SSET) \ -+ for ((NAME) = SSET_FIRST(SSET); \ -+ (NAME != NULL \ -+ ? (NEXT) = SSET_NEXT(SSET, NAME), true \ -+ : false); \ -+ (NAME) = (NEXT)) -+ -+#define SSET_FOR_EACH_SAFE_SHORT(NAME, SSET) \ -+ for (const char * NAME__next = \ -+ ((NAME) = SSET_FIRST(SSET), NULL); \ -+ (NAME != NULL \ -+ ? (NAME__next = SSET_NEXT(SSET, NAME), true) \ -+ : (NAME__next = NULL, false)); \ -+ (NAME) = NAME__next) -+ -+#define SSET_FOR_EACH_SAFE(...) \ -+ OVERLOAD_SAFE_MACRO(SSET_FOR_EACH_SAFE_LONG, \ -+ SSET_FOR_EACH_SAFE_SHORT, \ -+ 3, __VA_ARGS__) -+ -+const char **sset_array(const struct sset *); -+const char **sset_sort(const struct sset *); -+ -+/* Implementation helper macros. */ -+ -+#define SSET_NODE_FROM_HMAP_NODE(HMAP_NODE) \ -+ CONTAINER_OF(HMAP_NODE, struct sset_node, hmap_node) -+#define SSET_NAME_FROM_HMAP_NODE(HMAP_NODE) \ -+ HMAP_NODE == NULL \ -+ ? NULL \ -+ : (CONST_CAST(const char *, (SSET_NODE_FROM_HMAP_NODE(HMAP_NODE)->name))) -+#define SSET_NODE_FROM_NAME(NAME) CONTAINER_OF(NAME, struct sset_node, name) -+#define SSET_FIRST(SSET) \ -+ (BUILD_ASSERT_TYPE(SSET, struct sset *), \ -+ SSET_NAME_FROM_HMAP_NODE(hmap_first(&(SSET)->map))) -+#define SSET_NEXT(SSET, NAME) \ -+ (BUILD_ASSERT_TYPE(SSET, struct sset *), \ -+ SSET_NAME_FROM_HMAP_NODE( \ -+ hmap_next(&(SSET)->map, &SSET_NODE_FROM_NAME(NAME)->hmap_node))) -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* sset.h */ -Index: openvswitch-2.17.2/lib/stream.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream.h -+++ /dev/null -@@ -1,109 +0,0 @@ --/* -- * Copyright (c) 2009, 2010, 2011, 2013, 2015 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef STREAM_H --#define STREAM_H 1 -- --#include --#include --#include --#include --#include "openvswitch/types.h" --#include "socket-util.h" --#include "util.h" -- --struct pstream; --struct stream; --struct vlog_module; -- --void stream_usage(const char *name, bool active, bool passive, bool bootstrap); -- --/* Bidirectional byte streams. */ --int stream_verify_name(const char *name); --int stream_open(const char *name, struct stream **, uint8_t dscp); --int stream_open_block(int error, long long int timeout, struct stream **); --void stream_close(struct stream *); --const char *stream_get_name(const struct stream *); --int stream_connect(struct stream *); --int stream_recv(struct stream *, void *buffer, size_t n); --int stream_send(struct stream *, const void *buffer, size_t n); -- --void stream_run(struct stream *); --void stream_run_wait(struct stream *); -- --enum stream_wait_type { -- STREAM_CONNECT, -- STREAM_RECV, -- STREAM_SEND --}; --void stream_wait(struct stream *, enum stream_wait_type); --void stream_connect_wait(struct stream *); --void stream_recv_wait(struct stream *); --void stream_send_wait(struct stream *); --void stream_set_peer_id(struct stream *, const char *); --const char *stream_get_peer_id(const struct stream *); -- --/* Passive streams: listeners for incoming stream connections. */ --int pstream_verify_name(const char *name); --int pstream_open(const char *name, struct pstream **, uint8_t dscp); --const char *pstream_get_name(const struct pstream *); --void pstream_close(struct pstream *); --int pstream_accept(struct pstream *, struct stream **); --int pstream_accept_block(struct pstream *, struct stream **); --void pstream_wait(struct pstream *); -- --ovs_be16 pstream_get_bound_port(const struct pstream *); -- --/* Convenience functions. */ -- --int stream_open_with_default_port(const char *name, -- uint16_t default_port, -- struct stream **, -- uint8_t dscp); --int pstream_open_with_default_port(const char *name, -- uint16_t default_port, -- struct pstream **, -- uint8_t dscp); --bool stream_parse_target_with_default_port(const char *target, -- int default_port, -- struct sockaddr_storage *ss); --int stream_or_pstream_needs_probes(const char *name); -- --/* Error reporting. */ -- --enum stream_content_type { -- STREAM_UNKNOWN, -- STREAM_OPENFLOW, -- STREAM_SSL, -- STREAM_JSONRPC --}; -- --void stream_report_content(const void *, ssize_t, enum stream_content_type, -- struct vlog_module *, const char *stream_name); -- -- --/* Stream replay helpers. */ --void stream_replay_open_wfd(struct stream *, int open_result, -- const char *name); --void pstream_replay_open_wfd(struct pstream *, int listen_result, -- const char *name); --void stream_replay_close_wfd(struct stream *); --void pstream_replay_close_wfd(struct pstream *); --void stream_replay_write(struct stream *, const void *, int, bool is_read); --void pstream_replay_write_accept(struct pstream *, const struct stream *, -- int accept_result); -- --#endif /* stream.h */ -Index: openvswitch-2.17.2/include/internal/stream.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/stream.h -@@ -0,0 +1,109 @@ -+/* -+ * Copyright (c) 2009, 2010, 2011, 2013, 2015 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef STREAM_H -+#define STREAM_H 1 -+ -+#include -+#include -+#include -+#include -+#include "openvswitch/types.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" -+ -+struct pstream; -+struct stream; -+struct vlog_module; -+ -+void stream_usage(const char *name, bool active, bool passive, bool bootstrap); -+ -+/* Bidirectional byte streams. */ -+int stream_verify_name(const char *name); -+int stream_open(const char *name, struct stream **, uint8_t dscp); -+int stream_open_block(int error, long long int timeout, struct stream **); -+void stream_close(struct stream *); -+const char *stream_get_name(const struct stream *); -+int stream_connect(struct stream *); -+int stream_recv(struct stream *, void *buffer, size_t n); -+int stream_send(struct stream *, const void *buffer, size_t n); -+ -+void stream_run(struct stream *); -+void stream_run_wait(struct stream *); -+ -+enum stream_wait_type { -+ STREAM_CONNECT, -+ STREAM_RECV, -+ STREAM_SEND -+}; -+void stream_wait(struct stream *, enum stream_wait_type); -+void stream_connect_wait(struct stream *); -+void stream_recv_wait(struct stream *); -+void stream_send_wait(struct stream *); -+void stream_set_peer_id(struct stream *, const char *); -+const char *stream_get_peer_id(const struct stream *); -+ -+/* Passive streams: listeners for incoming stream connections. */ -+int pstream_verify_name(const char *name); -+int pstream_open(const char *name, struct pstream **, uint8_t dscp); -+const char *pstream_get_name(const struct pstream *); -+void pstream_close(struct pstream *); -+int pstream_accept(struct pstream *, struct stream **); -+int pstream_accept_block(struct pstream *, struct stream **); -+void pstream_wait(struct pstream *); -+ -+ovs_be16 pstream_get_bound_port(const struct pstream *); -+ -+/* Convenience functions. */ -+ -+int stream_open_with_default_port(const char *name, -+ uint16_t default_port, -+ struct stream **, -+ uint8_t dscp); -+int pstream_open_with_default_port(const char *name, -+ uint16_t default_port, -+ struct pstream **, -+ uint8_t dscp); -+bool stream_parse_target_with_default_port(const char *target, -+ int default_port, -+ struct sockaddr_storage *ss); -+int stream_or_pstream_needs_probes(const char *name); -+ -+/* Error reporting. */ -+ -+enum stream_content_type { -+ STREAM_UNKNOWN, -+ STREAM_OPENFLOW, -+ STREAM_SSL, -+ STREAM_JSONRPC -+}; -+ -+void stream_report_content(const void *, ssize_t, enum stream_content_type, -+ struct vlog_module *, const char *stream_name); -+ -+ -+/* Stream replay helpers. */ -+void stream_replay_open_wfd(struct stream *, int open_result, -+ const char *name); -+void pstream_replay_open_wfd(struct pstream *, int listen_result, -+ const char *name); -+void stream_replay_close_wfd(struct stream *); -+void pstream_replay_close_wfd(struct pstream *); -+void stream_replay_write(struct stream *, const void *, int, bool is_read); -+void pstream_replay_write_accept(struct pstream *, const struct stream *, -+ int accept_result); -+ -+#endif /* stream.h */ -Index: openvswitch-2.17.2/lib/timer.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/timer.h -+++ /dev/null -@@ -1,74 +0,0 @@ --/* -- * Copyright (c) 2011, 2013 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef TIMER_H --#define TIMER_H 1 -- --#include -- --#include "timeval.h" --#include "util.h" -- --struct timer { -- long long int t; --}; -- --long long int timer_msecs_until_expired(const struct timer *); --void timer_wait_at(const struct timer *, const char *where); --#define timer_wait(timer) timer_wait_at(timer, OVS_SOURCE_LOCATOR) -- --/* Causes 'timer' to expire when 'duration' milliseconds have passed. -- * -- * May be used to initialize 'timer'. */ --static inline void --timer_set_duration(struct timer *timer, long long int duration) --{ -- timer->t = time_msec() + duration; --} -- --/* Causes 'timer' never to expire. -- * -- * May be used to initialize 'timer'. */ --static inline void --timer_set_infinite(struct timer *timer) --{ -- timer->t = LLONG_MAX; --} -- --/* Causes 'timer' to expire immediately. -- * -- * May be used to initialize 'timer'. */ --static inline void --timer_set_expired(struct timer *timer) --{ -- timer->t = LLONG_MIN; --} -- --/* True if 'timer' has expired. */ --static inline bool --timer_expired(const struct timer *timer) --{ -- return time_msec() >= timer->t; --} -- --/* Returns ture if 'timer' will never expire. */ --static inline bool --timer_is_infinite(const struct timer *timer) --{ -- return timer->t == LLONG_MAX; --} -- --#endif /* timer.h */ -Index: openvswitch-2.17.2/include/internal/timer.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/timer.h -@@ -0,0 +1,74 @@ -+/* -+ * Copyright (c) 2011, 2013 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef TIMER_H -+#define TIMER_H 1 -+ -+#include -+ -+#include "internal/timeval.h" -+#include "internal/util.h" -+ -+struct timer { -+ long long int t; -+}; -+ -+long long int timer_msecs_until_expired(const struct timer *); -+void timer_wait_at(const struct timer *, const char *where); -+#define timer_wait(timer) timer_wait_at(timer, OVS_SOURCE_LOCATOR) -+ -+/* Causes 'timer' to expire when 'duration' milliseconds have passed. -+ * -+ * May be used to initialize 'timer'. */ -+static inline void -+timer_set_duration(struct timer *timer, long long int duration) -+{ -+ timer->t = time_msec() + duration; -+} -+ -+/* Causes 'timer' never to expire. -+ * -+ * May be used to initialize 'timer'. */ -+static inline void -+timer_set_infinite(struct timer *timer) -+{ -+ timer->t = LLONG_MAX; -+} -+ -+/* Causes 'timer' to expire immediately. -+ * -+ * May be used to initialize 'timer'. */ -+static inline void -+timer_set_expired(struct timer *timer) -+{ -+ timer->t = LLONG_MIN; -+} -+ -+/* True if 'timer' has expired. */ -+static inline bool -+timer_expired(const struct timer *timer) -+{ -+ return time_msec() >= timer->t; -+} -+ -+/* Returns ture if 'timer' will never expire. */ -+static inline bool -+timer_is_infinite(const struct timer *timer) -+{ -+ return timer->t == LLONG_MAX; -+} -+ -+#endif /* timer.h */ -Index: openvswitch-2.17.2/lib/timeval.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/timeval.h -+++ /dev/null -@@ -1,88 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef TIMEVAL_H --#define TIMEVAL_H 1 -- --#include --#include "openvswitch/type-props.h" --#include "util.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --struct ds; --struct pollfd; --struct timespec; --struct timeval; -- --/* POSIX allows floating-point time_t, but we don't support it. */ --BUILD_ASSERT_DECL(TYPE_IS_INTEGER(time_t)); -- --/* We do try to cater to unsigned time_t, but I want to know about it if we -- * ever encounter such a platform. */ --BUILD_ASSERT_DECL(TYPE_IS_SIGNED(time_t)); -- --#define TIME_MAX TYPE_MAXIMUM(time_t) --#define TIME_MIN TYPE_MINIMUM(time_t) -- --#ifdef _WIN32 --#define localtime_r(timep, result) localtime_s(result, timep) --#define gmtime_r(timep, result) gmtime_s(result, timep) --#endif /* _WIN32 */ -- --struct tm_msec { -- struct tm tm; -- int msec; --}; -- --time_t time_now(void); --time_t time_wall(void); --long long int time_msec(void); --long long int time_wall_msec(void); --long long int time_usec(void); --long long int time_wall_usec(void); --void time_timespec(struct timespec *); --void time_wall_timespec(struct timespec *); --void time_alarm(unsigned int secs); --int time_poll(struct pollfd *, int n_pollfds, HANDLE *handles, -- long long int timeout_when, int *elapsed); -- --long long int timespec_to_msec(const struct timespec *); --long long int timespec_to_usec(const struct timespec *); --long long int timeval_to_msec(const struct timeval *); --long long int timeval_to_usec(const struct timeval *); -- --struct tm_msec *localtime_msec(long long int now, struct tm_msec *result); --struct tm_msec *gmtime_msec(long long int now, struct tm_msec *result); --size_t strftime_msec(char *s, size_t max, const char *format, -- const struct tm_msec *); --void xgettimeofday(struct timeval *); --void xclock_gettime(clock_t, struct timespec *); --void nsec_to_timespec(long long int, struct timespec *); -- --int get_cpu_usage(void); -- --long long int time_boot_msec(void); -- --void timewarp_run(void); -- --#ifdef __cplusplus --} --#endif -- --#endif /* timeval.h */ -Index: openvswitch-2.17.2/include/internal/timeval.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/timeval.h -@@ -0,0 +1,88 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef TIMEVAL_H -+#define TIMEVAL_H 1 -+ -+#include -+#include "openvswitch/type-props.h" -+#include "internal/util.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct ds; -+struct pollfd; -+struct timespec; -+struct timeval; -+ -+/* POSIX allows floating-point time_t, but we don't support it. */ -+BUILD_ASSERT_DECL(TYPE_IS_INTEGER(time_t)); -+ -+/* We do try to cater to unsigned time_t, but I want to know about it if we -+ * ever encounter such a platform. */ -+BUILD_ASSERT_DECL(TYPE_IS_SIGNED(time_t)); -+ -+#define TIME_MAX TYPE_MAXIMUM(time_t) -+#define TIME_MIN TYPE_MINIMUM(time_t) -+ -+#ifdef _WIN32 -+#define localtime_r(timep, result) localtime_s(result, timep) -+#define gmtime_r(timep, result) gmtime_s(result, timep) -+#endif /* _WIN32 */ -+ -+struct tm_msec { -+ struct tm tm; -+ int msec; -+}; -+ -+time_t time_now(void); -+time_t time_wall(void); -+long long int time_msec(void); -+long long int time_wall_msec(void); -+long long int time_usec(void); -+long long int time_wall_usec(void); -+void time_timespec(struct timespec *); -+void time_wall_timespec(struct timespec *); -+void time_alarm(unsigned int secs); -+int time_poll(struct pollfd *, int n_pollfds, HANDLE *handles, -+ long long int timeout_when, int *elapsed); -+ -+long long int timespec_to_msec(const struct timespec *); -+long long int timespec_to_usec(const struct timespec *); -+long long int timeval_to_msec(const struct timeval *); -+long long int timeval_to_usec(const struct timeval *); -+ -+struct tm_msec *localtime_msec(long long int now, struct tm_msec *result); -+struct tm_msec *gmtime_msec(long long int now, struct tm_msec *result); -+size_t strftime_msec(char *s, size_t max, const char *format, -+ const struct tm_msec *); -+void xgettimeofday(struct timeval *); -+void xclock_gettime(clock_t, struct timespec *); -+void nsec_to_timespec(long long int, struct timespec *); -+ -+int get_cpu_usage(void); -+ -+long long int time_boot_msec(void); -+ -+void timewarp_run(void); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* timeval.h */ -Index: openvswitch-2.17.2/lib/tun-metadata.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/tun-metadata.h -+++ /dev/null -@@ -1,80 +0,0 @@ --/* -- * Copyright (c) 2015 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef TUN_METADATA_H --#define TUN_METADATA_H 1 -- --#include -- --#include "openvswitch/dynamic-string.h" --#include "netlink.h" --#include "openvswitch/ofpbuf.h" --#include "openflow/openflow.h" --#include "openvswitch/tun-metadata.h" -- --struct flow_tnl; --struct match; --struct mf_field; --union mf_value; --struct ofputil_tlv_table_mod; --struct ofputil_tlv_table_reply; --struct tun_table; -- --struct tun_table *tun_metadata_alloc(const struct tun_table *old_map); --void tun_metadata_free(struct tun_table *); --void tun_metadata_postpone_free(struct tun_table *); -- --enum ofperr tun_metadata_table_mod(struct ofputil_tlv_table_mod *, -- const struct tun_table *old_tab, -- struct tun_table **new_tab); --void tun_metadata_table_request(const struct tun_table *, -- struct ofputil_tlv_table_reply *); -- --void tun_metadata_read(const struct flow_tnl *, -- const struct mf_field *, union mf_value *); --void tun_metadata_write(struct flow_tnl *, -- const struct mf_field *, const union mf_value *); --void tun_metadata_delete(struct flow_tnl *, const struct mf_field *); --void tun_metadata_set_match(const struct mf_field *, -- const union mf_value *value, -- const union mf_value *mask, struct match *, -- char **err_str); --void tun_metadata_get_fmd(const struct flow_tnl *, struct match *flow_metadata); -- --void tun_metadata_from_geneve_nlattr(const struct nlattr *attr, bool is_mask, -- struct flow_tnl *tun); --void tun_metadata_to_geneve_nlattr(const struct flow_tnl *tun, -- const struct flow_tnl *flow, -- const struct ofpbuf *key, -- struct ofpbuf *); -- --int tun_metadata_from_geneve_udpif(const struct tun_table *, -- const struct flow_tnl *flow, -- const struct flow_tnl *src, -- struct flow_tnl *dst); --void tun_metadata_to_geneve_udpif_mask(const struct flow_tnl *flow_src, -- const struct flow_tnl *mask_src, -- const struct geneve_opt *flow_src_opt, -- int opts_len, struct geneve_opt *dst); -- --int tun_metadata_to_geneve_header(const struct flow_tnl *flow, -- struct geneve_opt *, bool *crit_opt); -- --void tun_metadata_to_nx_match(struct ofpbuf *b, enum ofp_version oxm, -- const struct match *); --void tun_metadata_match_format(struct ds *, const struct match *); -- --#endif /* tun-metadata.h */ -Index: openvswitch-2.17.2/include/internal/tun-metadata-private.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/tun-metadata-private.h -@@ -0,0 +1,80 @@ -+/* -+ * Copyright (c) 2015 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef TUN_METADATA_H -+#define TUN_METADATA_H 1 -+ -+#include -+ -+#include "openvswitch/dynamic-string.h" -+#include "internal/netlink.h" -+#include "openvswitch/ofpbuf.h" -+#include "openflow/openflow.h" -+#include "openvswitch/tun-metadata.h" -+ -+struct flow_tnl; -+struct match; -+struct mf_field; -+union mf_value; -+struct ofputil_tlv_table_mod; -+struct ofputil_tlv_table_reply; -+struct tun_table; -+ -+struct tun_table *tun_metadata_alloc(const struct tun_table *old_map); -+void tun_metadata_free(struct tun_table *); -+void tun_metadata_postpone_free(struct tun_table *); -+ -+enum ofperr tun_metadata_table_mod(struct ofputil_tlv_table_mod *, -+ const struct tun_table *old_tab, -+ struct tun_table **new_tab); -+void tun_metadata_table_request(const struct tun_table *, -+ struct ofputil_tlv_table_reply *); -+ -+void tun_metadata_read(const struct flow_tnl *, -+ const struct mf_field *, union mf_value *); -+void tun_metadata_write(struct flow_tnl *, -+ const struct mf_field *, const union mf_value *); -+void tun_metadata_delete(struct flow_tnl *, const struct mf_field *); -+void tun_metadata_set_match(const struct mf_field *, -+ const union mf_value *value, -+ const union mf_value *mask, struct match *, -+ char **err_str); -+void tun_metadata_get_fmd(const struct flow_tnl *, struct match *flow_metadata); -+ -+void tun_metadata_from_geneve_nlattr(const struct nlattr *attr, bool is_mask, -+ struct flow_tnl *tun); -+void tun_metadata_to_geneve_nlattr(const struct flow_tnl *tun, -+ const struct flow_tnl *flow, -+ const struct ofpbuf *key, -+ struct ofpbuf *); -+ -+int tun_metadata_from_geneve_udpif(const struct tun_table *, -+ const struct flow_tnl *flow, -+ const struct flow_tnl *src, -+ struct flow_tnl *dst); -+void tun_metadata_to_geneve_udpif_mask(const struct flow_tnl *flow_src, -+ const struct flow_tnl *mask_src, -+ const struct geneve_opt *flow_src_opt, -+ int opts_len, struct geneve_opt *dst); -+ -+int tun_metadata_to_geneve_header(const struct flow_tnl *flow, -+ struct geneve_opt *, bool *crit_opt); -+ -+void tun_metadata_to_nx_match(struct ofpbuf *b, enum ofp_version oxm, -+ const struct match *); -+void tun_metadata_match_format(struct ds *, const struct match *); -+ -+#endif /* tun-metadata.h */ -Index: openvswitch-2.17.2/lib/unaligned.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/unaligned.h -+++ /dev/null -@@ -1,322 +0,0 @@ --/* -- * Copyright (c) 2010, 2011, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef UNALIGNED_H --#define UNALIGNED_H 1 -- --#include --#include "byte-order.h" --#include "openvswitch/types.h" --#include "openvswitch/type-props.h" --#include "util.h" -- --/* Public API. */ --static inline uint16_t get_unaligned_u16(const uint16_t *); --static inline uint32_t get_unaligned_u32(const uint32_t *); --static inline void put_unaligned_u16(uint16_t *, uint16_t); --static inline void put_unaligned_u32(uint32_t *, uint32_t); --static inline void put_unaligned_u64(uint64_t *, uint64_t); -- --static inline ovs_be16 get_unaligned_be16(const ovs_be16 *); --static inline ovs_be32 get_unaligned_be32(const ovs_be32 *); --static inline ovs_be64 get_unaligned_be64(const ovs_be64 *); --static inline void put_unaligned_be16(ovs_be16 *, ovs_be16); --static inline void put_unaligned_be32(ovs_be32 *, ovs_be32); --static inline void put_unaligned_be64(ovs_be64 *, ovs_be64); -- --/* uint64_t get_unaligned_u64(uint64_t *p); -- * -- * Returns the value of the possibly misaligned uint64_t at 'p'. 'p' may -- * actually be any type that points to a 64-bit integer. That is, on Unix-like -- * 32-bit ABIs, it may point to an "unsigned long long int", and on Unix-like -- * 64-bit ABIs, it may point to an "unsigned long int" or an "unsigned long -- * long int". -- * -- * This is special-cased because on some Linux targets, the kernel __u64 is -- * unsigned long long int and the userspace uint64_t is unsigned long int, so -- * that any single function prototype would fail to accept one or the other. -- * -- * Below, "sizeof (*(P) % 1)" verifies that *P has an integer type, since -- * operands to % must be integers. -- */ --#define get_unaligned_u64(P) \ -- (BUILD_ASSERT(sizeof *(P) == 8), \ -- BUILD_ASSERT_GCCONLY(!TYPE_IS_SIGNED(typeof(*(P)))), \ -- (void) sizeof (*(P) % 1), \ -- get_unaligned_u64__((const uint64_t *) (P))) -- --#ifdef __GNUC__ --/* GCC implementations. */ --#define GCC_UNALIGNED_ACCESSORS(TYPE, ABBREV) \ --struct unaligned_##ABBREV { \ -- TYPE x __attribute__((__packed__)); \ --}; \ --static inline struct unaligned_##ABBREV * \ --unaligned_##ABBREV(const TYPE *p) \ --{ \ -- return (struct unaligned_##ABBREV *) p; \ --} \ -- \ --static inline TYPE \ --get_unaligned_##ABBREV(const TYPE *p) \ --{ \ -- return unaligned_##ABBREV(p)->x; \ --} \ -- \ --static inline void \ --put_unaligned_##ABBREV(TYPE *p, TYPE x) \ --{ \ -- unaligned_##ABBREV(p)->x = x; \ --} -- --GCC_UNALIGNED_ACCESSORS(uint16_t, u16); --GCC_UNALIGNED_ACCESSORS(uint32_t, u32); --GCC_UNALIGNED_ACCESSORS(uint64_t, u64__); /* Special case: see below. */ -- --GCC_UNALIGNED_ACCESSORS(ovs_be16, be16); --GCC_UNALIGNED_ACCESSORS(ovs_be32, be32); --GCC_UNALIGNED_ACCESSORS(ovs_be64, be64); --#else --/* Generic implementations. */ -- --static inline uint16_t get_unaligned_u16(const uint16_t *p_) --{ -- const uint8_t *p = (const uint8_t *) p_; -- return ntohs((p[0] << 8) | p[1]); --} -- --static inline void put_unaligned_u16(uint16_t *p_, uint16_t x_) --{ -- uint8_t *p = (uint8_t *) p_; -- uint16_t x = ntohs(x_); -- -- p[0] = x >> 8; -- p[1] = x; --} -- --static inline uint32_t get_unaligned_u32(const uint32_t *p_) --{ -- const uint8_t *p = (const uint8_t *) p_; -- return ntohl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); --} -- --static inline void put_unaligned_u32(uint32_t *p_, uint32_t x_) --{ -- uint8_t *p = (uint8_t *) p_; -- uint32_t x = ntohl(x_); -- -- p[0] = x >> 24; -- p[1] = x >> 16; -- p[2] = x >> 8; -- p[3] = x; --} -- --static inline uint64_t get_unaligned_u64__(const uint64_t *p_) --{ -- const uint8_t *p = (const uint8_t *) p_; -- return ntohll(((uint64_t) p[0] << 56) -- | ((uint64_t) p[1] << 48) -- | ((uint64_t) p[2] << 40) -- | ((uint64_t) p[3] << 32) -- | (p[4] << 24) -- | (p[5] << 16) -- | (p[6] << 8) -- | p[7]); --} -- --static inline void put_unaligned_u64__(uint64_t *p_, uint64_t x_) --{ -- uint8_t *p = (uint8_t *) p_; -- uint64_t x = ntohll(x_); -- -- p[0] = x >> 56; -- p[1] = x >> 48; -- p[2] = x >> 40; -- p[3] = x >> 32; -- p[4] = x >> 24; -- p[5] = x >> 16; -- p[6] = x >> 8; -- p[7] = x; --} -- --/* Only sparse cares about the difference between uint_t and ovs_be, and -- * that takes the GCC branch, so there's no point in working too hard on these -- * accessors. */ --#define get_unaligned_be16 get_unaligned_u16 --#define get_unaligned_be32 get_unaligned_u32 --#define put_unaligned_be16 put_unaligned_u16 --#define put_unaligned_be32 put_unaligned_u32 --#define put_unaligned_be64 put_unaligned_u64 -- --/* We do not #define get_unaligned_be64 as for the other be functions above, -- * because such a definition would mean that get_unaligned_be64() would have a -- * different interface in each branch of the #if: with GCC it would take a -- * "ovs_be64 *", with other compilers any pointer-to-64-bit-type (but not void -- * *). The latter means code like "get_unaligned_be64(ofpbuf_data(b))" would -- * work with GCC but not with other compilers, which is surprising and -- * undesirable. Hence this wrapper function. */ --static inline ovs_be64 --get_unaligned_be64(const ovs_be64 *p) --{ -- return get_unaligned_u64(p); --} --#endif -- --/* Stores 'x' at possibly misaligned address 'p'. -- * -- * put_unaligned_u64() could be overloaded in the same way as -- * get_unaligned_u64(), but so far it has not proven necessary. -- */ --static inline void --put_unaligned_u64(uint64_t *p, uint64_t x) --{ -- put_unaligned_u64__(p, x); --} -- --/* Returns the value in 'x'. */ --static inline uint32_t --get_16aligned_u32(const ovs_16aligned_u32 *x) --{ -- return ((uint32_t) x->hi << 16) | x->lo; --} -- --/* Stores 'value' in 'x'. */ --static inline void --put_16aligned_u32(ovs_16aligned_u32 *x, uint32_t value) --{ -- x->hi = value >> 16; -- x->lo = value; --} -- --/* Returns the value in 'x'. */ --static inline uint64_t --get_32aligned_u64(const ovs_32aligned_u64 *x) --{ -- return ((uint64_t) x->hi << 32) | x->lo; --} -- --/* Stores 'value' in 'x'. */ --static inline void --put_32aligned_u64(ovs_32aligned_u64 *x, uint64_t value) --{ -- x->hi = value >> 32; -- x->lo = value; --} -- --/* Returns the value in 'x'. */ --static inline ovs_u128 --get_32aligned_u128(const ovs_32aligned_u128 *x) --{ -- ovs_u128 u; -- u.u32[0] = x->u32[0]; -- u.u32[1] = x->u32[1]; -- u.u32[2] = x->u32[2]; -- u.u32[3] = x->u32[3]; -- return u; --} -- --/* Stores 'value' in 'x'. */ --static inline void --put_32aligned_u128(ovs_32aligned_u128 *x, ovs_u128 value) --{ -- x->u32[0] = value.u32[0]; -- x->u32[1] = value.u32[1]; -- x->u32[2] = value.u32[2]; -- x->u32[3] = value.u32[3]; --} -- --#ifndef __CHECKER__ --/* Returns the value of 'x'. */ --static inline ovs_be32 --get_16aligned_be32(const ovs_16aligned_be32 *x) --{ --#ifdef WORDS_BIGENDIAN -- return ((ovs_be32) x->hi << 16) | x->lo; --#else -- return ((ovs_be32) x->lo << 16) | x->hi; --#endif --} -- --/* Stores network byte order 'value' into 'x'. */ --static inline void --put_16aligned_be32(ovs_16aligned_be32 *x, ovs_be32 value) --{ --#if WORDS_BIGENDIAN -- x->hi = value >> 16; -- x->lo = value; --#else -- x->hi = value; -- x->lo = value >> 16; --#endif --} -- --/* Returns the value of 'x'. */ --static inline ovs_be64 --get_32aligned_be64(const ovs_32aligned_be64 *x) --{ --#ifdef WORDS_BIGENDIAN -- return ((ovs_be64) x->hi << 32) | x->lo; --#else -- return ((ovs_be64) x->lo << 32) | x->hi; --#endif --} -- --/* Stores network byte order 'value' into 'x'. */ --static inline void --put_32aligned_be64(ovs_32aligned_be64 *x, ovs_be64 value) --{ --#if WORDS_BIGENDIAN -- x->hi = value >> 32; -- x->lo = value; --#else -- x->hi = value; -- x->lo = value >> 32; --#endif --} -- --/* Returns the value of 'x'. */ --static inline ovs_be128 --get_32aligned_be128(const ovs_32aligned_be128 *x) --{ -- ovs_be128 u; -- u.be32[0] = x->be32[0]; -- u.be32[1] = x->be32[1]; -- u.be32[2] = x->be32[2]; -- u.be32[3] = x->be32[3]; -- return u; --} -- --/* Stores network byte order 'value' into 'x'. */ --static inline void --put_32aligned_be128(ovs_32aligned_be128 *x, ovs_be128 value) --{ -- x->be32[0] = value.be32[0]; -- x->be32[1] = value.be32[1]; -- x->be32[2] = value.be32[2]; -- x->be32[3] = value.be32[3]; --} --#else /* __CHECKER__ */ --/* Making sparse happy with these functions also makes them unreadable, so -- * don't bother to show it their implementations. */ --ovs_be32 get_16aligned_be32(const ovs_16aligned_be32 *); --void put_16aligned_be32(ovs_16aligned_be32 *, ovs_be32); --ovs_be64 get_32aligned_be64(const ovs_32aligned_be64 *); --void put_32aligned_be64(ovs_32aligned_be64 *, ovs_be64); --ovs_be128 get_32aligned_be128(const ovs_32aligned_be128 *); --void put_32aligned_be128(ovs_32aligned_be128 *, ovs_be128); --#endif -- --#endif /* unaligned.h */ -Index: openvswitch-2.17.2/include/internal/unaligned.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/unaligned.h -@@ -0,0 +1,322 @@ -+/* -+ * Copyright (c) 2010, 2011, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef UNALIGNED_H -+#define UNALIGNED_H 1 -+ -+#include -+#include "internal/byte-order.h" -+#include "openvswitch/types.h" -+#include "openvswitch/type-props.h" -+#include "internal/util.h" -+ -+/* Public API. */ -+static inline uint16_t get_unaligned_u16(const uint16_t *); -+static inline uint32_t get_unaligned_u32(const uint32_t *); -+static inline void put_unaligned_u16(uint16_t *, uint16_t); -+static inline void put_unaligned_u32(uint32_t *, uint32_t); -+static inline void put_unaligned_u64(uint64_t *, uint64_t); -+ -+static inline ovs_be16 get_unaligned_be16(const ovs_be16 *); -+static inline ovs_be32 get_unaligned_be32(const ovs_be32 *); -+static inline ovs_be64 get_unaligned_be64(const ovs_be64 *); -+static inline void put_unaligned_be16(ovs_be16 *, ovs_be16); -+static inline void put_unaligned_be32(ovs_be32 *, ovs_be32); -+static inline void put_unaligned_be64(ovs_be64 *, ovs_be64); -+ -+/* uint64_t get_unaligned_u64(uint64_t *p); -+ * -+ * Returns the value of the possibly misaligned uint64_t at 'p'. 'p' may -+ * actually be any type that points to a 64-bit integer. That is, on Unix-like -+ * 32-bit ABIs, it may point to an "unsigned long long int", and on Unix-like -+ * 64-bit ABIs, it may point to an "unsigned long int" or an "unsigned long -+ * long int". -+ * -+ * This is special-cased because on some Linux targets, the kernel __u64 is -+ * unsigned long long int and the userspace uint64_t is unsigned long int, so -+ * that any single function prototype would fail to accept one or the other. -+ * -+ * Below, "sizeof (*(P) % 1)" verifies that *P has an integer type, since -+ * operands to % must be integers. -+ */ -+#define get_unaligned_u64(P) \ -+ (BUILD_ASSERT(sizeof *(P) == 8), \ -+ BUILD_ASSERT_GCCONLY(!TYPE_IS_SIGNED(typeof(*(P)))), \ -+ (void) sizeof (*(P) % 1), \ -+ get_unaligned_u64__((const uint64_t *) (P))) -+ -+#ifdef __GNUC__ -+/* GCC implementations. */ -+#define GCC_UNALIGNED_ACCESSORS(TYPE, ABBREV) \ -+struct unaligned_##ABBREV { \ -+ TYPE x __attribute__((__packed__)); \ -+}; \ -+static inline struct unaligned_##ABBREV * \ -+unaligned_##ABBREV(const TYPE *p) \ -+{ \ -+ return (struct unaligned_##ABBREV *) p; \ -+} \ -+ \ -+static inline TYPE \ -+get_unaligned_##ABBREV(const TYPE *p) \ -+{ \ -+ return unaligned_##ABBREV(p)->x; \ -+} \ -+ \ -+static inline void \ -+put_unaligned_##ABBREV(TYPE *p, TYPE x) \ -+{ \ -+ unaligned_##ABBREV(p)->x = x; \ -+} -+ -+GCC_UNALIGNED_ACCESSORS(uint16_t, u16); -+GCC_UNALIGNED_ACCESSORS(uint32_t, u32); -+GCC_UNALIGNED_ACCESSORS(uint64_t, u64__); /* Special case: see below. */ -+ -+GCC_UNALIGNED_ACCESSORS(ovs_be16, be16); -+GCC_UNALIGNED_ACCESSORS(ovs_be32, be32); -+GCC_UNALIGNED_ACCESSORS(ovs_be64, be64); -+#else -+/* Generic implementations. */ -+ -+static inline uint16_t get_unaligned_u16(const uint16_t *p_) -+{ -+ const uint8_t *p = (const uint8_t *) p_; -+ return ntohs((p[0] << 8) | p[1]); -+} -+ -+static inline void put_unaligned_u16(uint16_t *p_, uint16_t x_) -+{ -+ uint8_t *p = (uint8_t *) p_; -+ uint16_t x = ntohs(x_); -+ -+ p[0] = x >> 8; -+ p[1] = x; -+} -+ -+static inline uint32_t get_unaligned_u32(const uint32_t *p_) -+{ -+ const uint8_t *p = (const uint8_t *) p_; -+ return ntohl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); -+} -+ -+static inline void put_unaligned_u32(uint32_t *p_, uint32_t x_) -+{ -+ uint8_t *p = (uint8_t *) p_; -+ uint32_t x = ntohl(x_); -+ -+ p[0] = x >> 24; -+ p[1] = x >> 16; -+ p[2] = x >> 8; -+ p[3] = x; -+} -+ -+static inline uint64_t get_unaligned_u64__(const uint64_t *p_) -+{ -+ const uint8_t *p = (const uint8_t *) p_; -+ return ntohll(((uint64_t) p[0] << 56) -+ | ((uint64_t) p[1] << 48) -+ | ((uint64_t) p[2] << 40) -+ | ((uint64_t) p[3] << 32) -+ | (p[4] << 24) -+ | (p[5] << 16) -+ | (p[6] << 8) -+ | p[7]); -+} -+ -+static inline void put_unaligned_u64__(uint64_t *p_, uint64_t x_) -+{ -+ uint8_t *p = (uint8_t *) p_; -+ uint64_t x = ntohll(x_); -+ -+ p[0] = x >> 56; -+ p[1] = x >> 48; -+ p[2] = x >> 40; -+ p[3] = x >> 32; -+ p[4] = x >> 24; -+ p[5] = x >> 16; -+ p[6] = x >> 8; -+ p[7] = x; -+} -+ -+/* Only sparse cares about the difference between uint_t and ovs_be, and -+ * that takes the GCC branch, so there's no point in working too hard on these -+ * accessors. */ -+#define get_unaligned_be16 get_unaligned_u16 -+#define get_unaligned_be32 get_unaligned_u32 -+#define put_unaligned_be16 put_unaligned_u16 -+#define put_unaligned_be32 put_unaligned_u32 -+#define put_unaligned_be64 put_unaligned_u64 -+ -+/* We do not #define get_unaligned_be64 as for the other be functions above, -+ * because such a definition would mean that get_unaligned_be64() would have a -+ * different interface in each branch of the #if: with GCC it would take a -+ * "ovs_be64 *", with other compilers any pointer-to-64-bit-type (but not void -+ * *). The latter means code like "get_unaligned_be64(ofpbuf_data(b))" would -+ * work with GCC but not with other compilers, which is surprising and -+ * undesirable. Hence this wrapper function. */ -+static inline ovs_be64 -+get_unaligned_be64(const ovs_be64 *p) -+{ -+ return get_unaligned_u64(p); -+} -+#endif -+ -+/* Stores 'x' at possibly misaligned address 'p'. -+ * -+ * put_unaligned_u64() could be overloaded in the same way as -+ * get_unaligned_u64(), but so far it has not proven necessary. -+ */ -+static inline void -+put_unaligned_u64(uint64_t *p, uint64_t x) -+{ -+ put_unaligned_u64__(p, x); -+} -+ -+/* Returns the value in 'x'. */ -+static inline uint32_t -+get_16aligned_u32(const ovs_16aligned_u32 *x) -+{ -+ return ((uint32_t) x->hi << 16) | x->lo; -+} -+ -+/* Stores 'value' in 'x'. */ -+static inline void -+put_16aligned_u32(ovs_16aligned_u32 *x, uint32_t value) -+{ -+ x->hi = value >> 16; -+ x->lo = value; -+} -+ -+/* Returns the value in 'x'. */ -+static inline uint64_t -+get_32aligned_u64(const ovs_32aligned_u64 *x) -+{ -+ return ((uint64_t) x->hi << 32) | x->lo; -+} -+ -+/* Stores 'value' in 'x'. */ -+static inline void -+put_32aligned_u64(ovs_32aligned_u64 *x, uint64_t value) -+{ -+ x->hi = value >> 32; -+ x->lo = value; -+} -+ -+/* Returns the value in 'x'. */ -+static inline ovs_u128 -+get_32aligned_u128(const ovs_32aligned_u128 *x) -+{ -+ ovs_u128 u; -+ u.u32[0] = x->u32[0]; -+ u.u32[1] = x->u32[1]; -+ u.u32[2] = x->u32[2]; -+ u.u32[3] = x->u32[3]; -+ return u; -+} -+ -+/* Stores 'value' in 'x'. */ -+static inline void -+put_32aligned_u128(ovs_32aligned_u128 *x, ovs_u128 value) -+{ -+ x->u32[0] = value.u32[0]; -+ x->u32[1] = value.u32[1]; -+ x->u32[2] = value.u32[2]; -+ x->u32[3] = value.u32[3]; -+} -+ -+#ifndef __CHECKER__ -+/* Returns the value of 'x'. */ -+static inline ovs_be32 -+get_16aligned_be32(const ovs_16aligned_be32 *x) -+{ -+#ifdef WORDS_BIGENDIAN -+ return ((ovs_be32) x->hi << 16) | x->lo; -+#else -+ return ((ovs_be32) x->lo << 16) | x->hi; -+#endif -+} -+ -+/* Stores network byte order 'value' into 'x'. */ -+static inline void -+put_16aligned_be32(ovs_16aligned_be32 *x, ovs_be32 value) -+{ -+#if WORDS_BIGENDIAN -+ x->hi = value >> 16; -+ x->lo = value; -+#else -+ x->hi = value; -+ x->lo = value >> 16; -+#endif -+} -+ -+/* Returns the value of 'x'. */ -+static inline ovs_be64 -+get_32aligned_be64(const ovs_32aligned_be64 *x) -+{ -+#ifdef WORDS_BIGENDIAN -+ return ((ovs_be64) x->hi << 32) | x->lo; -+#else -+ return ((ovs_be64) x->lo << 32) | x->hi; -+#endif -+} -+ -+/* Stores network byte order 'value' into 'x'. */ -+static inline void -+put_32aligned_be64(ovs_32aligned_be64 *x, ovs_be64 value) -+{ -+#if WORDS_BIGENDIAN -+ x->hi = value >> 32; -+ x->lo = value; -+#else -+ x->hi = value; -+ x->lo = value >> 32; -+#endif -+} -+ -+/* Returns the value of 'x'. */ -+static inline ovs_be128 -+get_32aligned_be128(const ovs_32aligned_be128 *x) -+{ -+ ovs_be128 u; -+ u.be32[0] = x->be32[0]; -+ u.be32[1] = x->be32[1]; -+ u.be32[2] = x->be32[2]; -+ u.be32[3] = x->be32[3]; -+ return u; -+} -+ -+/* Stores network byte order 'value' into 'x'. */ -+static inline void -+put_32aligned_be128(ovs_32aligned_be128 *x, ovs_be128 value) -+{ -+ x->be32[0] = value.be32[0]; -+ x->be32[1] = value.be32[1]; -+ x->be32[2] = value.be32[2]; -+ x->be32[3] = value.be32[3]; -+} -+#else /* __CHECKER__ */ -+/* Making sparse happy with these functions also makes them unreadable, so -+ * don't bother to show it their implementations. */ -+ovs_be32 get_16aligned_be32(const ovs_16aligned_be32 *); -+void put_16aligned_be32(ovs_16aligned_be32 *, ovs_be32); -+ovs_be64 get_32aligned_be64(const ovs_32aligned_be64 *); -+void put_32aligned_be64(ovs_32aligned_be64 *, ovs_be64); -+ovs_be128 get_32aligned_be128(const ovs_32aligned_be128 *); -+void put_32aligned_be128(ovs_32aligned_be128 *, ovs_be128); -+#endif -+ -+#endif /* unaligned.h */ -Index: openvswitch-2.17.2/include/internal/util.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/util.h -@@ -0,0 +1,603 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef UTIL_H -+#define UTIL_H 1 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "openvswitch/compiler.h" -+#include "openvswitch/util.h" -+#if defined(__aarch64__) && __GNUC__ >= 6 -+#include -+#endif -+ -+extern char *program_name; -+ -+#define __ARRAY_SIZE_NOCHECK(ARRAY) (sizeof(ARRAY) / sizeof((ARRAY)[0])) -+#if __GNUC__ && !defined(__cplusplus) -+/* return 0 for array types, 1 otherwise */ -+#define __ARRAY_CHECK(ARRAY) \ -+ !__builtin_types_compatible_p(typeof(ARRAY), typeof(&ARRAY[0])) -+ -+/* compile-time fail if not array */ -+#define __ARRAY_FAIL(ARRAY) (sizeof(char[-2*!__ARRAY_CHECK(ARRAY)])) -+#define __ARRAY_SIZE(ARRAY) \ -+ __builtin_choose_expr(__ARRAY_CHECK(ARRAY), \ -+ __ARRAY_SIZE_NOCHECK(ARRAY), __ARRAY_FAIL(ARRAY)) -+#elif defined(__cplusplus) -+#define __ARRAY_SIZE(ARRAY) ( \ -+ 0 * sizeof(reinterpret_cast(ARRAY)) + \ -+ 0 * sizeof(::Bad_arg_to_ARRAY_SIZE::check_type((ARRAY), &(ARRAY))) + \ -+ sizeof(ARRAY) / sizeof((ARRAY)[0]) ) -+ -+struct Bad_arg_to_ARRAY_SIZE { -+ class Is_pointer; -+ class Is_array {}; -+ template -+ static Is_pointer check_type(const T *, const T * const *); -+ static Is_array check_type(const void *, const void *); -+}; -+#else -+#define __ARRAY_SIZE(ARRAY) __ARRAY_SIZE_NOCHECK(ARRAY) -+#endif -+ -+ -+/* This system's cache line size, in bytes. -+ * Being wrong hurts performance but not correctness. */ -+#define CACHE_LINE_SIZE 64 -+BUILD_ASSERT_DECL(IS_POW2(CACHE_LINE_SIZE)); -+ -+/* Cacheline marking is typically done using zero-sized array. -+ * However MSVC doesn't like zero-sized array in struct/union. -+ * C4200: https://msdn.microsoft.com/en-us/library/79wf64bc.aspx -+ */ -+typedef uint8_t OVS_CACHE_LINE_MARKER[1]; -+ -+static inline void -+ovs_prefetch_range(const void *start, size_t size) -+{ -+ const char *addr = (const char *)start; -+ size_t ofs; -+ -+ for (ofs = 0; ofs < size; ofs += CACHE_LINE_SIZE) { -+ OVS_PREFETCH(addr + ofs); -+ } -+} -+ -+#ifndef MIN -+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) -+#endif -+ -+#ifndef MAX -+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) -+#endif -+ -+/* Comparisons for ints with modular arithmetic */ -+#define INT_MOD_LT(a,b) ((int) ((a)-(b)) < 0) -+#define INT_MOD_LEQ(a,b) ((int) ((a)-(b)) <= 0) -+#define INT_MOD_GT(a,b) ((int) ((a)-(b)) > 0) -+#define INT_MOD_GEQ(a,b) ((int) ((a)-(b)) >= 0) -+ -+#define INT_MOD_MIN(a, b) ((INT_MOD_LT(a, b)) ? (a) : (b)) -+#define INT_MOD_MAX(a, b) ((INT_MOD_GT(a, b)) ? (a) : (b)) -+ -+#define OVS_NOT_REACHED() abort() -+ -+/* Joins two token expanding the arguments if they are macros. -+ * -+ * For token concatenation the circumlocution is needed for the -+ * expansion. */ -+#define OVS_JOIN2(X, Y) X##Y -+#define OVS_JOIN(X, Y) OVS_JOIN2(X, Y) -+ -+/* Use "%"PRIuSIZE to format size_t with printf(). */ -+#ifdef _WIN32 -+#define PRIdSIZE "Id" -+#define PRIiSIZE "Ii" -+#define PRIoSIZE "Io" -+#define PRIuSIZE "Iu" -+#define PRIxSIZE "Ix" -+#define PRIXSIZE "IX" -+#else -+#define PRIdSIZE "zd" -+#define PRIiSIZE "zi" -+#define PRIoSIZE "zo" -+#define PRIuSIZE "zu" -+#define PRIxSIZE "zx" -+#define PRIXSIZE "zX" -+#endif -+ -+#ifndef _WIN32 -+typedef uint32_t HANDLE; -+#endif -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define set_program_name(name) \ -+ ovs_set_program_name(name, OVS_PACKAGE_VERSION) -+ -+const char *get_subprogram_name(void); -+ void set_subprogram_name(const char *); -+ -+unsigned int get_page_size(void); -+long long int get_boot_time(void); -+ -+void ctl_timeout_setup(unsigned int secs); -+ -+void ovs_print_version(uint8_t min_ofp, uint8_t max_ofp); -+ -+void set_memory_locked(void); -+bool memory_locked(void); -+ -+OVS_NO_RETURN void out_of_memory(void); -+ -+/* Allocation wrappers that abort if memory is exhausted. */ -+void *xmalloc(size_t) OVS_MALLOC_LIKE; -+void *xcalloc(size_t, size_t) OVS_MALLOC_LIKE; -+void *xzalloc(size_t) OVS_MALLOC_LIKE; -+void *xrealloc(void *, size_t); -+void *xmemdup(const void *, size_t) OVS_MALLOC_LIKE; -+char *xmemdup0(const char *, size_t) OVS_MALLOC_LIKE; -+char *xstrdup(const char *) OVS_MALLOC_LIKE; -+char *nullable_xstrdup(const char *) OVS_MALLOC_LIKE; -+bool nullable_string_is_equal(const char *a, const char *b); -+char *xasprintf(const char *format, ...) OVS_PRINTF_FORMAT(1, 2) OVS_MALLOC_LIKE; -+char *xvasprintf(const char *format, va_list) OVS_PRINTF_FORMAT(1, 0) OVS_MALLOC_LIKE; -+void *x2nrealloc(void *p, size_t *n, size_t s); -+ -+/* Allocation wrappers for specialized situations where coverage counters -+ * cannot be used. */ -+void *xmalloc__(size_t) OVS_MALLOC_LIKE; -+void *xcalloc__(size_t, size_t) OVS_MALLOC_LIKE; -+void *xzalloc__(size_t) OVS_MALLOC_LIKE; -+void *xrealloc__(void *, size_t); -+ -+void *xmalloc_cacheline(size_t) OVS_MALLOC_LIKE; -+void *xzalloc_cacheline(size_t) OVS_MALLOC_LIKE; -+void free_cacheline(void *); -+ -+void ovs_strlcpy(char *dst, const char *src, size_t size); -+void ovs_strzcpy(char *dst, const char *src, size_t size); -+ -+int string_ends_with(const char *str, const char *suffix); -+ -+void *xmalloc_pagealign(size_t) OVS_MALLOC_LIKE; -+void free_pagealign(void *); -+void *xmalloc_size_align(size_t, size_t) OVS_MALLOC_LIKE; -+void free_size_align(void *); -+ -+/* The C standards say that neither the 'dst' nor 'src' argument to -+ * memcpy() may be null, even if 'n' is zero. This wrapper tolerates -+ * the null case. */ -+static inline void -+nullable_memcpy(void *dst, const void *src, size_t n) -+{ -+ if (n) { -+ memcpy(dst, src, n); -+ } -+} -+ -+/* The C standards say that the 'dst' argument to memset may not be -+ * null, even if 'n' is zero. This wrapper tolerates the null case. */ -+static inline void -+nullable_memset(void *dst, int c, size_t n) -+{ -+ if (n) { -+ memset(dst, c, n); -+ } -+} -+ -+/* Copy string SRC to DST, but no more bytes than the shorter of DST or SRC. -+ * DST and SRC must both be char arrays, not pointers, and with GNU C, this -+ * raises a compiler error if either DST or SRC is a pointer instead of an -+ * array. */ -+#define ovs_strlcpy_arrays(DST, SRC) \ -+ ovs_strlcpy(DST, SRC, MIN(ARRAY_SIZE(DST), ARRAY_SIZE(SRC))) -+ -+OVS_NO_RETURN void ovs_abort(int err_no, const char *format, ...) -+ OVS_PRINTF_FORMAT(2, 3); -+OVS_NO_RETURN void ovs_abort_valist(int err_no, const char *format, va_list) -+ OVS_PRINTF_FORMAT(2, 0); -+OVS_NO_RETURN void ovs_fatal(int err_no, const char *format, ...) -+ OVS_PRINTF_FORMAT(2, 3); -+OVS_NO_RETURN void ovs_fatal_valist(int err_no, const char *format, va_list) -+ OVS_PRINTF_FORMAT(2, 0); -+void ovs_error(int err_no, const char *format, ...) OVS_PRINTF_FORMAT(2, 3); -+void ovs_error_valist(int err_no, const char *format, va_list) -+ OVS_PRINTF_FORMAT(2, 0); -+const char *ovs_retval_to_string(int); -+const char *ovs_strerror(int); -+void ovs_hex_dump(FILE *, const void *, size_t, uintptr_t offset, bool ascii); -+ -+bool str_to_int(const char *, int base, int *); -+bool str_to_long(const char *, int base, long *); -+bool str_to_llong(const char *, int base, long long *); -+bool str_to_llong_with_tail(const char *, char **, int base, long long *); -+bool str_to_uint(const char *, int base, unsigned int *); -+bool str_to_ullong(const char *, int base, unsigned long long *); -+bool str_to_llong_range(const char *, int base, long long *, long long *); -+ -+bool ovs_scan(const char *s, const char *format, ...) OVS_SCANF_FORMAT(2, 3); -+bool ovs_scan_len(const char *s, int *n, const char *format, ...); -+ -+bool str_to_double(const char *, double *); -+ -+int hexit_value(unsigned char c); -+uintmax_t hexits_value(const char *s, size_t n, bool *ok); -+ -+int parse_int_string(const char *s, uint8_t *valuep, int field_width, -+ char **tail); -+ -+const char *english_list_delimiter(size_t index, size_t total); -+ -+char *get_cwd(void); -+#ifndef _WIN32 -+char *dir_name(const char *file_name); -+char *base_name(const char *file_name); -+#endif -+char *abs_file_name(const char *dir, const char *file_name); -+bool is_file_name_absolute(const char *); -+ -+char *follow_symlinks(const char *filename); -+ -+void ignore(bool x OVS_UNUSED); -+ -+/* Bitwise tests. */ -+ -+/* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */ -+#if __GNUC__ >= 4 -+static inline int -+raw_ctz(uint64_t n) -+{ -+ /* With GCC 4.7 on 32-bit x86, if a 32-bit integer is passed as 'n', using -+ * a plain __builtin_ctzll() here always generates an out-of-line function -+ * call. The test below helps it to emit a single 'bsf' instruction. */ -+ return (__builtin_constant_p(n <= UINT32_MAX) && n <= UINT32_MAX -+ ? __builtin_ctz(n) -+ : __builtin_ctzll(n)); -+} -+ -+static inline int -+raw_clz64(uint64_t n) -+{ -+ return __builtin_clzll(n); -+} -+#elif _MSC_VER -+static inline int -+raw_ctz(uint64_t n) -+{ -+#ifdef _WIN64 -+ unsigned long r = 0; -+ _BitScanForward64(&r, n); -+ return r; -+#else -+ unsigned long low = n, high, r = 0; -+ if (_BitScanForward(&r, low)) { -+ return r; -+ } -+ high = n >> 32; -+ _BitScanForward(&r, high); -+ return r + 32; -+#endif -+} -+ -+static inline int -+raw_clz64(uint64_t n) -+{ -+#ifdef _WIN64 -+ unsigned long r = 0; -+ _BitScanReverse64(&r, n); -+ return 63 - r; -+#else -+ unsigned long low, high = n >> 32, r = 0; -+ if (_BitScanReverse(&r, high)) { -+ return 31 - r; -+ } -+ low = n; -+ _BitScanReverse(&r, low); -+ return 63 - r; -+#endif -+} -+#else -+/* Defined in util.c. */ -+int raw_ctz(uint64_t n); -+int raw_clz64(uint64_t n); -+#endif -+ -+/* Returns the number of trailing 0-bits in 'n', or 32 if 'n' is 0. */ -+static inline int -+ctz32(uint32_t n) -+{ -+ return n ? raw_ctz(n) : 32; -+} -+ -+/* Returns the number of trailing 0-bits in 'n', or 64 if 'n' is 0. */ -+static inline int -+ctz64(uint64_t n) -+{ -+ return n ? raw_ctz(n) : 64; -+} -+ -+/* Returns the number of leading 0-bits in 'n', or 32 if 'n' is 0. */ -+static inline int -+clz32(uint32_t n) -+{ -+ return n ? raw_clz64(n) - 32 : 32; -+} -+ -+/* Returns the number of leading 0-bits in 'n', or 64 if 'n' is 0. */ -+static inline int -+clz64(uint64_t n) -+{ -+ return n ? raw_clz64(n) : 64; -+} -+ -+/* Given a word 'n', calculates floor(log_2('n')). This is equivalent -+ * to finding the bit position of the most significant one bit in 'n'. It is -+ * an error to call this function with 'n' == 0. */ -+static inline int -+log_2_floor(uint64_t n) -+{ -+ return 63 - raw_clz64(n); -+} -+ -+/* Given a word 'n', calculates ceil(log_2('n')). It is an error to -+ * call this function with 'n' == 0. */ -+static inline int -+log_2_ceil(uint64_t n) -+{ -+ return log_2_floor(n) + !is_pow2(n); -+} -+ -+/* unsigned int count_1bits(uint64_t x): -+ * -+ * Returns the number of 1-bits in 'x', between 0 and 64 inclusive. */ -+#if UINTPTR_MAX == UINT64_MAX -+static inline unsigned int -+count_1bits(uint64_t x) -+{ -+#if (__GNUC__ >= 4 && __POPCNT__) || (defined(__aarch64__) && __GNUC__ >= 7) -+ return __builtin_popcountll(x); -+#elif defined(__aarch64__) && __GNUC__ >= 6 -+ return vaddv_u8(vcnt_u8(vcreate_u8(x))); -+#else -+ /* This portable implementation is the fastest one we know of for 64 -+ * bits, and about 3x faster than GCC 4.7 __builtin_popcountll(). */ -+ const uint64_t h55 = UINT64_C(0x5555555555555555); -+ const uint64_t h33 = UINT64_C(0x3333333333333333); -+ const uint64_t h0F = UINT64_C(0x0F0F0F0F0F0F0F0F); -+ const uint64_t h01 = UINT64_C(0x0101010101010101); -+ x -= (x >> 1) & h55; /* Count of each 2 bits in-place. */ -+ x = (x & h33) + ((x >> 2) & h33); /* Count of each 4 bits in-place. */ -+ x = (x + (x >> 4)) & h0F; /* Count of each 8 bits in-place. */ -+ return (x * h01) >> 56; /* Sum of all bytes. */ -+#endif -+} -+#else /* Not 64-bit. */ -+#if __GNUC__ >= 4 && __POPCNT__ -+static inline unsigned int -+count_1bits_32__(uint32_t x) -+{ -+ return __builtin_popcount(x); -+} -+#else -+#define NEED_COUNT_1BITS_8 1 -+extern const uint8_t count_1bits_8[256]; -+static inline unsigned int -+count_1bits_32__(uint32_t x) -+{ -+ /* This portable implementation is the fastest one we know of for 32 bits, -+ * and faster than GCC __builtin_popcount(). */ -+ return (count_1bits_8[x & 0xff] + -+ count_1bits_8[(x >> 8) & 0xff] + -+ count_1bits_8[(x >> 16) & 0xff] + -+ count_1bits_8[x >> 24]); -+} -+#endif -+static inline unsigned int -+count_1bits(uint64_t x) -+{ -+ return count_1bits_32__(x) + count_1bits_32__(x >> 32); -+} -+#endif -+ -+/* Returns the rightmost 1-bit in 'x' (e.g. 01011000 => 00001000), or 0 if 'x' -+ * is 0. */ -+static inline uintmax_t -+rightmost_1bit(uintmax_t x) -+{ -+ return x & -x; -+} -+ -+/* Returns 'x' with its rightmost 1-bit changed to a zero (e.g. 01011000 => -+ * 01010000), or 0 if 'x' is 0. */ -+static inline uintmax_t -+zero_rightmost_1bit(uintmax_t x) -+{ -+ return x & (x - 1); -+} -+ -+/* Returns the index of the rightmost 1-bit in 'x' (e.g. 01011000 => 3), or an -+ * undefined value if 'x' is 0. */ -+static inline int -+rightmost_1bit_idx(uint64_t x) -+{ -+ return ctz64(x); -+} -+ -+/* Returns the index of the leftmost 1-bit in 'x' (e.g. 01011000 => 6), or an -+ * undefined value if 'x' is 0. */ -+static inline uint32_t -+leftmost_1bit_idx(uint64_t x) -+{ -+ return log_2_floor(x); -+} -+ -+/* Return a ovs_be32 prefix in network byte order with 'plen' highest bits set. -+ * Shift with 32 is undefined behavior, but we rather use 64-bit shift than -+ * compare. */ -+static inline ovs_be32 be32_prefix_mask(int plen) -+{ -+ return htonl((uint64_t)UINT32_MAX << (32 - plen)); -+} -+ -+/* Returns true if the 1-bits in 'super' are a superset of the 1-bits in 'sub', -+ * false otherwise. */ -+static inline bool -+uint_is_superset(uintmax_t super, uintmax_t sub) -+{ -+ return (super & sub) == sub; -+} -+ -+/* Returns true if the 1-bits in 'super' are a superset of the 1-bits in 'sub', -+ * false otherwise. */ -+static inline bool -+be16_is_superset(ovs_be16 super, ovs_be16 sub) -+{ -+ return (super & sub) == sub; -+} -+ -+/* Returns true if the 1-bits in 'super' are a superset of the 1-bits in 'sub', -+ * false otherwise. */ -+static inline bool -+be32_is_superset(ovs_be32 super, ovs_be32 sub) -+{ -+ return (super & sub) == sub; -+} -+ -+/* Returns true if the 1-bits in 'super' are a superset of the 1-bits in 'sub', -+ * false otherwise. */ -+static inline bool -+be64_is_superset(ovs_be64 super, ovs_be64 sub) -+{ -+ return (super & sub) == sub; -+} -+ -+bool is_all_zeros(const void *, size_t); -+bool is_all_ones(const void *, size_t); -+bool is_all_byte(const void *, size_t, uint8_t byte); -+void or_bytes(void *dst, const void *src, size_t n); -+void bitwise_copy(const void *src, unsigned int src_len, unsigned int src_ofs, -+ void *dst, unsigned int dst_len, unsigned int dst_ofs, -+ unsigned int n_bits); -+void bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs, -+ unsigned int n_bits); -+void bitwise_one(void *dst_, unsigned int dst_len, unsigned dst_ofs, -+ unsigned int n_bits); -+bool bitwise_is_all_zeros(const void *, unsigned int len, unsigned int ofs, -+ unsigned int n_bits); -+unsigned int bitwise_scan(const void *, unsigned int len, -+ bool target, unsigned int start, unsigned int end); -+int bitwise_rscan(const void *, unsigned int len, bool target, -+ int start, int end); -+void bitwise_put(uint64_t value, -+ void *dst, unsigned int dst_len, unsigned int dst_ofs, -+ unsigned int n_bits); -+uint64_t bitwise_get(const void *src, unsigned int src_len, -+ unsigned int src_ofs, unsigned int n_bits); -+bool bitwise_get_bit(const void *src, unsigned int len, unsigned int ofs); -+void bitwise_put0(void *dst, unsigned int len, unsigned int ofs); -+void bitwise_put1(void *dst, unsigned int len, unsigned int ofs); -+void bitwise_put_bit(void *dst, unsigned int len, unsigned int ofs, bool); -+void bitwise_toggle_bit(void *dst, unsigned int len, unsigned int ofs); -+ -+/* Returns non-zero if the parameters have equal value. */ -+static inline int -+ovs_u128_equals(const ovs_u128 a, const ovs_u128 b) -+{ -+ return (a.u64.hi == b.u64.hi) && (a.u64.lo == b.u64.lo); -+} -+ -+/* Returns true if 'val' is 0. */ -+static inline bool -+ovs_u128_is_zero(const ovs_u128 val) -+{ -+ return !(val.u64.hi || val.u64.lo); -+} -+ -+/* Returns true if 'val' is all ones. */ -+static inline bool -+ovs_u128_is_ones(const ovs_u128 val) -+{ -+ return ovs_u128_equals(val, OVS_U128_MAX); -+} -+ -+/* Returns non-zero if the parameters have equal value. */ -+static inline int -+ovs_be128_equals(const ovs_be128 a, const ovs_be128 b) -+{ -+ return (a.be64.hi == b.be64.hi) && (a.be64.lo == b.be64.lo); -+} -+ -+/* Returns true if 'val' is 0. */ -+static inline bool -+ovs_be128_is_zero(const ovs_be128 val) -+{ -+ return !(val.be64.hi || val.be64.lo); -+} -+ -+static inline ovs_u128 -+ovs_u128_and(const ovs_u128 a, const ovs_u128 b) -+{ -+ ovs_u128 dst; -+ -+ dst.u64.hi = a.u64.hi & b.u64.hi; -+ dst.u64.lo = a.u64.lo & b.u64.lo; -+ -+ return dst; -+} -+ -+static inline bool -+ovs_be128_is_superset(ovs_be128 super, ovs_be128 sub) -+{ -+ return (be64_is_superset(super.be64.hi, sub.be64.hi) && -+ be64_is_superset(super.be64.lo, sub.be64.lo)); -+} -+ -+static inline bool -+ovs_u128_is_superset(ovs_u128 super, ovs_u128 sub) -+{ -+ return (uint_is_superset(super.u64.hi, sub.u64.hi) && -+ uint_is_superset(super.u64.lo, sub.u64.lo)); -+} -+ -+void xsleep(unsigned int seconds); -+void xnanosleep(uint64_t nanoseconds); -+ -+bool is_stdout_a_tty(void); -+ -+#ifdef _WIN32 -+ -+char *ovs_format_message(int error); -+char *ovs_lasterror_to_string(void); -+int ftruncate(int fd, off_t length); -+#endif -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* util.h */ -Index: openvswitch-2.17.2/lib/versions.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/versions.h -+++ /dev/null -@@ -1,74 +0,0 @@ --/* -- * Copyright (c) 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef VERSIONS_H --#define VERSIONS_H 1 -- --#include "ovs-atomic.h" --#include "openvswitch/type-props.h" -- --typedef uint64_t ovs_version_t; -- --#define OVS_VERSION_MIN 0 /* Default version number to use. */ --#define OVS_VERSION_MAX (TYPE_MAXIMUM(ovs_version_t) - 1) --#define OVS_VERSION_NOT_REMOVED TYPE_MAXIMUM(ovs_version_t) -- --/* -- * OVS_VERSION_NOT_REMOVED has a special meaning for 'remove_version', -- * meaning that the rule has been added but not yet removed. -- */ --struct versions { -- ovs_version_t add_version; /* Version object was added in. */ -- ATOMIC(ovs_version_t) remove_version; /* Version object is removed in. */ --}; -- --#define VERSIONS_INITIALIZER(ADD, REMOVE) \ -- (struct versions){ ADD, ATOMIC_VAR_INIT(REMOVE) } -- --static inline void --versions_set_remove_version(struct versions *versions, ovs_version_t version) --{ -- atomic_store_relaxed(&versions->remove_version, version); --} -- --static inline bool --versions_visible_in_version(const struct versions *versions, -- ovs_version_t version) --{ -- ovs_version_t remove_version; -- -- /* C11 does not want to access an atomic via a const object pointer. */ -- atomic_read_relaxed(&CONST_CAST(struct versions *, -- versions)->remove_version, -- &remove_version); -- -- return versions->add_version <= version && version < remove_version; --} -- --static inline bool --versions_is_eventually_invisible(const struct versions *versions) --{ -- ovs_version_t remove_version; -- -- /* C11 does not want to access an atomic via a const object pointer. */ -- atomic_read_relaxed(&CONST_CAST(struct versions *, -- versions)->remove_version, -- &remove_version); -- -- return remove_version < OVS_VERSION_NOT_REMOVED; --} -- --#endif /* VERSIONS_H */ -Index: openvswitch-2.17.2/include/internal/versions.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/versions.h -@@ -0,0 +1,74 @@ -+/* -+ * Copyright (c) 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef VERSIONS_H -+#define VERSIONS_H 1 -+ -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/type-props.h" -+ -+typedef uint64_t ovs_version_t; -+ -+#define OVS_VERSION_MIN 0 /* Default version number to use. */ -+#define OVS_VERSION_MAX (TYPE_MAXIMUM(ovs_version_t) - 1) -+#define OVS_VERSION_NOT_REMOVED TYPE_MAXIMUM(ovs_version_t) -+ -+/* -+ * OVS_VERSION_NOT_REMOVED has a special meaning for 'remove_version', -+ * meaning that the rule has been added but not yet removed. -+ */ -+struct versions { -+ ovs_version_t add_version; /* Version object was added in. */ -+ ATOMIC(ovs_version_t) remove_version; /* Version object is removed in. */ -+}; -+ -+#define VERSIONS_INITIALIZER(ADD, REMOVE) \ -+ (struct versions){ ADD, ATOMIC_VAR_INIT(REMOVE) } -+ -+static inline void -+versions_set_remove_version(struct versions *versions, ovs_version_t version) -+{ -+ atomic_store_relaxed(&versions->remove_version, version); -+} -+ -+static inline bool -+versions_visible_in_version(const struct versions *versions, -+ ovs_version_t version) -+{ -+ ovs_version_t remove_version; -+ -+ /* C11 does not want to access an atomic via a const object pointer. */ -+ atomic_read_relaxed(&CONST_CAST(struct versions *, -+ versions)->remove_version, -+ &remove_version); -+ -+ return versions->add_version <= version && version < remove_version; -+} -+ -+static inline bool -+versions_is_eventually_invisible(const struct versions *versions) -+{ -+ ovs_version_t remove_version; -+ -+ /* C11 does not want to access an atomic via a const object pointer. */ -+ atomic_read_relaxed(&CONST_CAST(struct versions *, -+ versions)->remove_version, -+ &remove_version); -+ -+ return remove_version < OVS_VERSION_NOT_REMOVED; -+} -+ -+#endif /* VERSIONS_H */ -Index: openvswitch-2.17.2/include/openvswitch/automake.mk -=================================================================== ---- openvswitch-2.17.2.orig/include/openvswitch/automake.mk -+++ openvswitch-2.17.2/include/openvswitch/automake.mk -@@ -1,5 +1,7 @@ - openvswitchincludedir = $(includedir)/openvswitch - openvswitchinclude_HEADERS = \ -+ include/odp-netlink.h \ -+ include/odp-netlink-macros.h \ - include/openvswitch/compiler.h \ - include/openvswitch/dynamic-string.h \ - include/openvswitch/hmap.h \ -@@ -34,6 +36,20 @@ openvswitchinclude_HEADERS = \ - include/openvswitch/ofp-switch.h \ - include/openvswitch/ofp-table.h \ - include/openvswitch/ofp-util.h \ -+ include/openvswitch/ovs-atomic.h \ -+ include/openvswitch/ovs-numa.h \ -+ include/openvswitch/ovs-rcu.h \ -+ include/openvswitch/ovs-thread.h \ -+ include/openvswitch/ovsdb-cs.h \ -+ include/openvswitch/ovsdb-condition.h \ -+ include/openvswitch/ovsdb-data.h \ -+ include/openvswitch/ovsdb-error.h \ -+ include/openvswitch/ovsdb-idl.h \ -+ include/openvswitch/ovsdb-idl-provider.h \ -+ include/openvswitch/ovsdb-map-op.h \ -+ include/openvswitch/ovsdb-set-op.h \ -+ include/openvswitch/ovsdb-parser.h \ -+ include/openvswitch/ovsdb-types.h \ - include/openvswitch/packets.h \ - include/openvswitch/poll-loop.h \ - include/openvswitch/rconn.h \ -Index: openvswitch-2.17.2/lib/ovs-atomic.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic.h -+++ /dev/null -@@ -1,671 +0,0 @@ --/* -- * Copyright (c) 2013, 2014, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVS_ATOMIC_H --#define OVS_ATOMIC_H 1 -- --/* Atomic operations. -- * -- * This library implements atomic operations with an API based on the one -- * defined in C11. It includes multiple implementations for compilers and -- * libraries with varying degrees of built-in support for C11, including a -- * fallback implementation for systems that have pthreads but no other support -- * for atomics. -- * -- * This comment describes the common features of all the implementations. -- * -- * -- * Types -- * ===== -- * -- * The following atomic types are supported as typedefs for atomic versions of -- * the listed ordinary types: -- * -- * ordinary type atomic version -- * ------------------- ---------------------- -- * bool atomic_bool -- * -- * char atomic_char -- * signed char atomic_schar -- * unsigned char atomic_uchar -- * -- * short atomic_short -- * unsigned short atomic_ushort -- * -- * int atomic_int -- * unsigned int atomic_uint -- * -- * long atomic_long -- * unsigned long atomic_ulong -- * -- * long long atomic_llong -- * unsigned long long atomic_ullong -- * -- * size_t atomic_size_t -- * ptrdiff_t atomic_ptrdiff_t -- * -- * intmax_t atomic_intmax_t -- * uintmax_t atomic_uintmax_t -- * -- * intptr_t atomic_intptr_t -- * uintptr_t atomic_uintptr_t -- * -- * uint8_t atomic_uint8_t (*) -- * uint16_t atomic_uint16_t (*) -- * uint32_t atomic_uint32_t (*) -- * int8_t atomic_int8_t (*) -- * int16_t atomic_int16_t (*) -- * int32_t atomic_int32_t (*) -- * uint64_t atomic_uint64_t (*) -- * int64_t atomic_int64_t (*) -- * -- * (*) Not specified by C11. -- * -- * Atomic types may also be obtained via ATOMIC(TYPE), e.g. ATOMIC(void *). -- * Only basic integer types and pointer types can be made atomic this way, -- * e.g. atomic structs are not supported. -- * -- * The atomic version of a type doesn't necessarily have the same size or -- * representation as the ordinary version; for example, atomic_int might be a -- * typedef for a struct. The range of an atomic type does match the range of -- * the corresponding ordinary type. -- * -- * C11 says that one may use the _Atomic keyword in place of the typedef name, -- * e.g. "_Atomic int" instead of "atomic_int". This library doesn't support -- * that. -- * -- * -- * Life Cycle -- * ========== -- * -- * To initialize an atomic variable at its point of definition, use -- * ATOMIC_VAR_INIT: -- * -- * static atomic_int ai = ATOMIC_VAR_INIT(123); -- * -- * To initialize an atomic variable in code, use atomic_init(): -- * -- * static atomic_int ai; -- * ... -- * atomic_init(&ai, 123); -- * -- * -- * Barriers -- * ======== -- * -- * enum memory_order specifies the strictness of a memory barrier. It has the -- * following values: -- * -- * memory_order_relaxed: -- * -- * Only atomicity is provided, does not imply any memory ordering with -- * respect to any other variable (atomic or not). Relaxed accesses to -- * the same atomic variable will be performed in the program order. -- * The compiler and CPU are free to move memory accesses to other -- * variables past the atomic operation. -- * -- * memory_order_consume: -- * -- * Memory accesses with data dependency on the result of the consume -- * operation (atomic_read_explicit, or a load operation preceding a -- * atomic_thread_fence) will not be moved prior to the consume -- * barrier. Non-data-dependent loads and stores can be reordered to -- * happen before the consume barrier. -- * -- * RCU is the prime example of the use of the consume barrier: The -- * consume barrier guarantees that reads from a RCU protected object -- * are performed after the RCU protected pointer is read. A -- * corresponding release barrier is used to store the modified RCU -- * protected pointer after the RCU protected object has been fully -- * constructed. The synchronization between these barriers prevents -- * the RCU "consumer" from seeing uninitialized data. -- * -- * May not be used with atomic_store_explicit(), as consume semantics -- * applies only to atomic loads. -- * -- * memory_order_acquire: -- * -- * Memory accesses after an acquire barrier cannot be moved before the -- * barrier. Memory accesses before an acquire barrier *can* be moved -- * after it. -- * -- * An atomic_thread_fence with memory_order_acquire does not have a -- * load operation by itself; it prevents all following memory accesses -- * from moving prior to preceding loads. -- * -- * May not be used with atomic_store_explicit(), as acquire semantics -- * applies only to atomic loads. -- * -- * memory_order_release: -- * -- * Memory accesses before a release barrier cannot be moved after the -- * barrier. Memory accesses after a release barrier *can* be moved -- * before it. -- * -- * An atomic_thread_fence with memory_order_release does not have a -- * store operation by itself; it prevents all preceding memory accesses -- * from moving past subsequent stores. -- * -- * May not be used with atomic_read_explicit(), as release semantics -- * applies only to atomic stores. -- * -- * memory_order_acq_rel: -- * -- * Memory accesses cannot be moved across an acquire-release barrier in -- * either direction. -- * -- * May only be used with atomic read-modify-write operations, as both -- * load and store operation is required for acquire-release semantics. -- * -- * An atomic_thread_fence with memory_order_acq_rel does not have -- * either load or store operation by itself; it prevents all following -- * memory accesses from moving prior to preceding loads and all -- * preceding memory accesses from moving past subsequent stores. -- * -- * memory_order_seq_cst: -- * -- * Prevents movement of memory accesses like an acquire-release barrier, -- * but whereas acquire-release synchronizes cooperating threads (using -- * the same atomic variable), sequential-consistency synchronizes the -- * whole system, providing a total order for stores on all atomic -- * variables. -- * -- * OVS atomics require the memory_order to be passed as a compile-time constant -- * value, as some compiler implementations may perform poorly if the memory -- * order parameter is passed in as a run-time value. -- * -- * The following functions insert explicit barriers. Most of the other atomic -- * functions also include barriers. -- * -- * void atomic_thread_fence(memory_order order); -- * -- * Inserts a barrier of the specified type. -- * -- * For memory_order_relaxed, this is a no-op. -- * -- * void atomic_signal_fence(memory_order order); -- * -- * Inserts a barrier of the specified type, but only with respect to -- * signal handlers in the same thread as the barrier. This is -- * basically a compiler optimization barrier, except for -- * memory_order_relaxed, which is a no-op. -- * -- * -- * Atomic Operations -- * ================= -- * -- * In this section, A is an atomic type and C is the corresponding non-atomic -- * type. -- * -- * The "store", "exchange", and "compare_exchange" primitives match C11: -- * -- * void atomic_store(A *object, C value); -- * void atomic_store_explicit(A *object, C value, memory_order); -- * -- * Atomically stores 'value' into '*object', respecting the given -- * memory order (or memory_order_seq_cst for atomic_store()). -- * -- * bool atomic_compare_exchange_strong(A *object, C *expected, C desired); -- * bool atomic_compare_exchange_weak(A *object, C *expected, C desired); -- * bool atomic_compare_exchange_strong_explicit(A *object, C *expected, -- * C desired, -- * memory_order success, -- * memory_order failure); -- * bool atomic_compare_exchange_weak_explicit(A *object, C *expected, -- * C desired, -- * memory_order success, -- * memory_order failure); -- * -- * Atomically loads '*object' and compares it with '*expected' and if -- * equal, stores 'desired' into '*object' (an atomic read-modify-write -- * operation) and returns true, and if non-equal, stores the actual -- * value of '*object' into '*expected' (an atomic load operation) and -- * returns false. The memory order for the successful case (atomic -- * read-modify-write operation) is 'success', and for the unsuccessful -- * case (atomic load operation) 'failure'. 'failure' may not be -- * stronger than 'success'. -- * -- * The weak forms may fail (returning false) also when '*object' equals -- * '*expected'. The strong form can be implemented by the weak form in -- * a loop. Some platforms can implement the weak form more -- * efficiently, so it should be used if the application will need to -- * loop anyway. -- * -- * C atomic_exchange(A *object, C desired); -- * C atomic_exchange_explicit(A *object, C desired, memory_order); -- * -- * Atomically stores 'desired' into '*object', returning the value -- * previously held. -- * -- * The following primitives differ from the C11 ones (and have different names) -- * because there does not appear to be a way to implement the standard -- * primitives in standard C: -- * -- * void atomic_read(A *src, C *dst); -- * void atomic_read_explicit(A *src, C *dst, memory_order); -- * -- * Atomically loads a value from 'src', writing the value read into -- * '*dst', respecting the given memory order (or memory_order_seq_cst -- * for atomic_read()). -- * -- * void atomic_add(A *rmw, C arg, C *orig); -- * void atomic_sub(A *rmw, C arg, C *orig); -- * void atomic_or(A *rmw, C arg, C *orig); -- * void atomic_xor(A *rmw, C arg, C *orig); -- * void atomic_and(A *rmw, C arg, C *orig); -- * void atomic_add_explicit(A *rmw, C arg, C *orig, memory_order); -- * void atomic_sub_explicit(A *rmw, C arg, C *orig, memory_order); -- * void atomic_or_explicit(A *rmw, C arg, C *orig, memory_order); -- * void atomic_xor_explicit(A *rmw, C arg, C *orig, memory_order); -- * void atomic_and_explicit(A *rmw, C arg, C *orig, memory_order); -- * -- * Atomically applies the given operation, with 'arg' as the second -- * operand, to '*rmw', and stores the original value of '*rmw' into -- * '*orig', respecting the given memory order (or memory_order_seq_cst -- * if none is specified). -- * -- * The results are similar to those that would be obtained with +=, -=, -- * |=, ^=, or |= on non-atomic types. -- * -- * -- * atomic_flag -- * =========== -- * -- * atomic_flag is a typedef for a type with two states, set and clear, that -- * provides atomic test-and-set functionality. -- * -- * -- * Life Cycle -- * ---------- -- * -- * ATOMIC_FLAG_INIT is an initializer for atomic_flag. The initial state is -- * "clear". -- * -- * An atomic_flag may also be initialized at runtime with atomic_flag_clear(). -- * -- * -- * Operations -- * ---------- -- * -- * The following functions are available. -- * -- * bool atomic_flag_test_and_set(atomic_flag *object) -- * bool atomic_flag_test_and_set_explicit(atomic_flag *object, -- * memory_order); -- * -- * Atomically sets '*object', respecting the given memory order (or -- * memory_order_seq_cst for atomic_flag_test_and_set()). Returns the -- * previous value of the flag (false for clear, true for set). -- * -- * void atomic_flag_clear(atomic_flag *object); -- * void atomic_flag_clear_explicit(atomic_flag *object, memory_order); -- * -- * Atomically clears '*object', respecting the given memory order (or -- * memory_order_seq_cst for atomic_flag_clear()). -- */ -- --#include --#include --#include --#include --#include --#include "openvswitch/compiler.h" --#include "util.h" -- --#define IN_OVS_ATOMIC_H -- #if __CHECKER__ -- /* sparse doesn't understand some GCC extensions we use. */ -- #include "ovs-atomic-pthreads.h" -- #elif __has_extension(c_atomic) -- #include "ovs-atomic-clang.h" -- #elif HAVE_ATOMIC && __cplusplus >= 201103L -- #include "ovs-atomic-c++.h" -- #elif HAVE_STDATOMIC_H && !defined(__cplusplus) -- #include "ovs-atomic-c11.h" -- #elif __GNUC__ >= 5 && !defined(__cplusplus) -- #error "GCC 5+ should have " -- #elif __GNUC__ >= 5 || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 7) -- #include "ovs-atomic-gcc4.7+.h" -- #elif __GNUC__ && defined(__x86_64__) -- #include "ovs-atomic-x86_64.h" -- #elif __GNUC__ && defined(__i386__) -- #include "ovs-atomic-i586.h" -- #elif HAVE_GCC4_ATOMICS -- #include "ovs-atomic-gcc4+.h" -- #elif _MSC_VER -- #include "ovs-atomic-msvc.h" -- #else -- /* ovs-atomic-pthreads implementation is provided for portability. -- * It might be too slow for real use because Open vSwitch is -- * optimized for platforms where real atomic ops are available. */ -- #include "ovs-atomic-pthreads.h" -- #endif --#undef IN_OVS_ATOMIC_H -- --#ifndef OMIT_STANDARD_ATOMIC_TYPES --typedef ATOMIC(bool) atomic_bool; -- --typedef ATOMIC(char) atomic_char; --typedef ATOMIC(signed char) atomic_schar; --typedef ATOMIC(unsigned char) atomic_uchar; -- --typedef ATOMIC(short) atomic_short; --typedef ATOMIC(unsigned short) atomic_ushort; -- --typedef ATOMIC(int) atomic_int; --typedef ATOMIC(unsigned int) atomic_uint; -- --typedef ATOMIC(long) atomic_long; --typedef ATOMIC(unsigned long) atomic_ulong; -- --typedef ATOMIC(long long) atomic_llong; --typedef ATOMIC(unsigned long long) atomic_ullong; -- --typedef ATOMIC(size_t) atomic_size_t; --typedef ATOMIC(ptrdiff_t) atomic_ptrdiff_t; -- --typedef ATOMIC(intmax_t) atomic_intmax_t; --typedef ATOMIC(uintmax_t) atomic_uintmax_t; -- --typedef ATOMIC(intptr_t) atomic_intptr_t; --typedef ATOMIC(uintptr_t) atomic_uintptr_t; --#endif /* !OMIT_STANDARD_ATOMIC_TYPES */ -- --/* Nonstandard atomic types. */ --typedef ATOMIC(uint8_t) atomic_uint8_t; --typedef ATOMIC(uint16_t) atomic_uint16_t; --typedef ATOMIC(uint32_t) atomic_uint32_t; --typedef ATOMIC(uint64_t) atomic_uint64_t; -- --typedef ATOMIC(int8_t) atomic_int8_t; --typedef ATOMIC(int16_t) atomic_int16_t; --typedef ATOMIC(int32_t) atomic_int32_t; --typedef ATOMIC(int64_t) atomic_int64_t; -- --/* Relaxed atomic operations. -- * -- * When an operation on an atomic variable is not expected to synchronize -- * with operations on other (atomic or non-atomic) variables, no memory -- * barriers are needed and the relaxed memory ordering can be used. These -- * macros make such uses less daunting, but not invisible. */ --#define atomic_store_relaxed(VAR, VALUE) \ -- atomic_store_explicit(VAR, VALUE, memory_order_relaxed) --#define atomic_read_relaxed(VAR, DST) \ -- atomic_read_explicit(VAR, DST, memory_order_relaxed) --#define atomic_compare_exchange_strong_relaxed(DST, EXP, SRC) \ -- atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -- memory_order_relaxed, \ -- memory_order_relaxed) --#define atomic_compare_exchange_weak_relaxed(DST, EXP, SRC) \ -- atomic_compare_exchange_weak_explicit(DST, EXP, SRC, \ -- memory_order_relaxed, \ -- memory_order_relaxed) --#define atomic_add_relaxed(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, ARG, ORIG, memory_order_relaxed) --#define atomic_sub_relaxed(RMW, ARG, ORIG) \ -- atomic_sub_explicit(RMW, ARG, ORIG, memory_order_relaxed) --#define atomic_or_relaxed(RMW, ARG, ORIG) \ -- atomic_or_explicit(RMW, ARG, ORIG, memory_order_relaxed) --#define atomic_xor_relaxed(RMW, ARG, ORIG) \ -- atomic_xor_explicit(RMW, ARG, ORIG, memory_order_relaxed) --#define atomic_and_relaxed(RMW, ARG, ORIG) \ -- atomic_and_explicit(RMW, ARG, ORIG, memory_order_relaxed) --#define atomic_flag_test_and_set_relaxed(FLAG) \ -- atomic_flag_test_and_set_explicit(FLAG, memory_order_relaxed) --#define atomic_flag_clear_relaxed(FLAG) \ -- atomic_flag_clear_explicit(FLAG, memory_order_relaxed) -- --/* A simplified atomic count. Does not provide any synchronization with any -- * other variables. -- * -- * Typically a counter is not used to synchronize the state of any other -- * variables (with the notable exception of reference count, below). -- * This abstraction releaves the user from the memory order considerations, -- * and may make the code easier to read. -- * -- * We only support the unsigned int counters, as those are the most common. */ --typedef struct atomic_count { -- atomic_uint count; --} atomic_count; -- --#define ATOMIC_COUNT_INIT(VALUE) { VALUE } -- --static inline void --atomic_count_init(atomic_count *count, unsigned int value) --{ -- atomic_init(&count->count, value); --} -- --static inline unsigned int --atomic_count_inc(atomic_count *count) --{ -- unsigned int old; -- -- atomic_add_relaxed(&count->count, 1u, &old); -- -- return old; --} -- --static inline unsigned int --atomic_count_dec(atomic_count *count) --{ -- unsigned int old; -- -- atomic_sub_relaxed(&count->count, 1u, &old); -- -- return old; --} -- --static inline unsigned int --atomic_count_get(atomic_count *count) --{ -- unsigned int value; -- -- atomic_read_relaxed(&count->count, &value); -- -- return value; --} -- --static inline void --atomic_count_set(atomic_count *count, unsigned int value) --{ -- atomic_store_relaxed(&count->count, value); --} -- --static inline uint64_t --atomic_count_inc64(atomic_uint64_t *counter) --{ -- uint64_t old; -- -- atomic_add_relaxed(counter, 1ull, &old); -- -- return old; --} -- --static inline uint64_t --atomic_count_dec64(atomic_uint64_t *counter) --{ -- uint64_t old; -- -- atomic_sub_relaxed(counter, 1ull, &old); -- -- return old; --} -- --static inline uint64_t --atomic_count_get64(atomic_uint64_t *counter) --{ -- uint64_t value; -- -- atomic_read_relaxed(counter, &value); -- -- return value; --} -- --static inline void --atomic_count_set64(atomic_uint64_t *counter, uint64_t value) --{ -- atomic_store_relaxed(counter, value); --} -- --/* Reference count. */ --struct ovs_refcount { -- atomic_uint count; --}; -- --/* Initializes 'refcount'. The reference count is initially 1. */ --static inline void --ovs_refcount_init(struct ovs_refcount *refcount) --{ -- atomic_init(&refcount->count, 1u); --} -- --/* Increments 'refcount'. -- * -- * Does not provide a memory barrier, as the calling thread must have -- * protected access to the object already. */ --static inline void --ovs_refcount_ref(struct ovs_refcount *refcount) --{ -- unsigned int old_refcount; -- -- atomic_add_explicit(&refcount->count, 1u, &old_refcount, -- memory_order_relaxed); -- ovs_assert(old_refcount > 0); --} -- --/* Decrements 'refcount' and returns the previous reference count. Often used -- * in this form: -- * -- * if (ovs_refcount_unref(&object->ref_cnt) == 1) { -- * ...uninitialize object... -- * free(object); -- * } -- * -- * Provides a release barrier making the preceding loads and stores to not be -- * reordered after the unref, and in case of the last reference provides also -- * an acquire barrier to keep all the following uninitialization from being -- * reordered before the atomic decrement operation. Together these synchronize -- * any concurrent unref operations between each other. */ --static inline unsigned int --ovs_refcount_unref(struct ovs_refcount *refcount) --{ -- unsigned int old_refcount; -- -- atomic_sub_explicit(&refcount->count, 1u, &old_refcount, -- memory_order_release); -- ovs_assert(old_refcount > 0); -- if (old_refcount == 1) { -- /* 'memory_order_release' above means that there are no (reordered) -- * accesses to the protected object from any thread at this point. -- * An acquire barrier is needed to keep all subsequent access to the -- * object's memory from being reordered before the atomic operation -- * above. */ -- atomic_thread_fence(memory_order_acquire); -- } -- return old_refcount; --} -- --/* Reads and returns 'refcount_''s current reference count. -- * -- * Does not provide a memory barrier. -- * -- * Rarely useful. */ --static inline unsigned int --ovs_refcount_read(const struct ovs_refcount *refcount_) --{ -- struct ovs_refcount *refcount -- = CONST_CAST(struct ovs_refcount *, refcount_); -- unsigned int count; -- -- atomic_read_explicit(&refcount->count, &count, memory_order_relaxed); -- return count; --} -- --/* Increments 'refcount', but only if it is non-zero. -- * -- * This may only be called for an object which is RCU protected during -- * this call. This implies that its possible destruction is postponed -- * until all current RCU threads quiesce. -- * -- * Returns false if the refcount was zero. In this case the object may -- * be safely accessed until the current thread quiesces, but no additional -- * references to the object may be taken. -- * -- * Does not provide a memory barrier, as the calling thread must have -- * RCU protected access to the object already. -- * -- * It is critical that we never increment a zero refcount to a -- * non-zero value, as whenever a refcount reaches the zero value, the -- * protected object may be irrevocably scheduled for deletion. */ --static inline bool --ovs_refcount_try_ref_rcu(struct ovs_refcount *refcount) --{ -- unsigned int count; -- -- atomic_read_explicit(&refcount->count, &count, memory_order_relaxed); -- do { -- if (count == 0) { -- return false; -- } -- } while (!atomic_compare_exchange_weak_explicit(&refcount->count, &count, -- count + 1, -- memory_order_relaxed, -- memory_order_relaxed)); -- return true; --} -- --/* Decrements 'refcount' and returns the previous reference count. To -- * be used only when a memory barrier is already provided for the -- * protected object independently. -- * -- * For example: -- * -- * if (ovs_refcount_unref_relaxed(&object->ref_cnt) == 1) { -- * ovsrcu_postpone(destructor_function, object); -- * } -- * -- * Here RCU quiescing already provides a full memory barrier. No additional -- * barriers are needed here. -- * -- * Or: -- * -- * if (stp && ovs_refcount_unref_relaxed(&stp->ref_cnt) == 1) { -- * ovs_mutex_lock(&mutex); -- * ovs_list_remove(&stp->node); -- * ovs_mutex_unlock(&mutex); -- * free(stp->name); -- * free(stp); -- * } -- * -- * Here a mutex is used to guard access to all of 'stp' apart from -- * 'ref_cnt'. Hence all changes to 'stp' by other threads must be -- * visible when we get the mutex, and no access after the unlock can -- * be reordered to happen prior the lock operation. No additional -- * barriers are needed here. -- */ --static inline unsigned int --ovs_refcount_unref_relaxed(struct ovs_refcount *refcount) --{ -- unsigned int old_refcount; -- -- atomic_sub_explicit(&refcount->count, 1u, &old_refcount, -- memory_order_relaxed); -- ovs_assert(old_refcount > 0); -- return old_refcount; --} -- --#endif /* ovs-atomic.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovs-atomic.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovs-atomic.h -@@ -0,0 +1,679 @@ -+/* -+ * Copyright (c) 2013, 2014, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVS_ATOMIC_H -+#define OVS_ATOMIC_H 1 -+ -+/* Atomic operations. -+ * -+ * This library implements atomic operations with an API based on the one -+ * defined in C11. It includes multiple implementations for compilers and -+ * libraries with varying degrees of built-in support for C11, including a -+ * fallback implementation for systems that have pthreads but no other support -+ * for atomics. -+ * -+ * This comment describes the common features of all the implementations. -+ * -+ * -+ * Types -+ * ===== -+ * -+ * The following atomic types are supported as typedefs for atomic versions of -+ * the listed ordinary types: -+ * -+ * ordinary type atomic version -+ * ------------------- ---------------------- -+ * bool atomic_bool -+ * -+ * char atomic_char -+ * signed char atomic_schar -+ * unsigned char atomic_uchar -+ * -+ * short atomic_short -+ * unsigned short atomic_ushort -+ * -+ * int atomic_int -+ * unsigned int atomic_uint -+ * -+ * long atomic_long -+ * unsigned long atomic_ulong -+ * -+ * long long atomic_llong -+ * unsigned long long atomic_ullong -+ * -+ * size_t atomic_size_t -+ * ptrdiff_t atomic_ptrdiff_t -+ * -+ * intmax_t atomic_intmax_t -+ * uintmax_t atomic_uintmax_t -+ * -+ * intptr_t atomic_intptr_t -+ * uintptr_t atomic_uintptr_t -+ * -+ * uint8_t atomic_uint8_t (*) -+ * uint16_t atomic_uint16_t (*) -+ * uint32_t atomic_uint32_t (*) -+ * int8_t atomic_int8_t (*) -+ * int16_t atomic_int16_t (*) -+ * int32_t atomic_int32_t (*) -+ * uint64_t atomic_uint64_t (*) -+ * int64_t atomic_int64_t (*) -+ * -+ * (*) Not specified by C11. -+ * -+ * Atomic types may also be obtained via ATOMIC(TYPE), e.g. ATOMIC(void *). -+ * Only basic integer types and pointer types can be made atomic this way, -+ * e.g. atomic structs are not supported. -+ * -+ * The atomic version of a type doesn't necessarily have the same size or -+ * representation as the ordinary version; for example, atomic_int might be a -+ * typedef for a struct. The range of an atomic type does match the range of -+ * the corresponding ordinary type. -+ * -+ * C11 says that one may use the _Atomic keyword in place of the typedef name, -+ * e.g. "_Atomic int" instead of "atomic_int". This library doesn't support -+ * that. -+ * -+ * -+ * Life Cycle -+ * ========== -+ * -+ * To initialize an atomic variable at its point of definition, use -+ * ATOMIC_VAR_INIT: -+ * -+ * static atomic_int ai = ATOMIC_VAR_INIT(123); -+ * -+ * To initialize an atomic variable in code, use atomic_init(): -+ * -+ * static atomic_int ai; -+ * ... -+ * atomic_init(&ai, 123); -+ * -+ * -+ * Barriers -+ * ======== -+ * -+ * enum memory_order specifies the strictness of a memory barrier. It has the -+ * following values: -+ * -+ * memory_order_relaxed: -+ * -+ * Only atomicity is provided, does not imply any memory ordering with -+ * respect to any other variable (atomic or not). Relaxed accesses to -+ * the same atomic variable will be performed in the program order. -+ * The compiler and CPU are free to move memory accesses to other -+ * variables past the atomic operation. -+ * -+ * memory_order_consume: -+ * -+ * Memory accesses with data dependency on the result of the consume -+ * operation (atomic_read_explicit, or a load operation preceding a -+ * atomic_thread_fence) will not be moved prior to the consume -+ * barrier. Non-data-dependent loads and stores can be reordered to -+ * happen before the consume barrier. -+ * -+ * RCU is the prime example of the use of the consume barrier: The -+ * consume barrier guarantees that reads from a RCU protected object -+ * are performed after the RCU protected pointer is read. A -+ * corresponding release barrier is used to store the modified RCU -+ * protected pointer after the RCU protected object has been fully -+ * constructed. The synchronization between these barriers prevents -+ * the RCU "consumer" from seeing uninitialized data. -+ * -+ * May not be used with atomic_store_explicit(), as consume semantics -+ * applies only to atomic loads. -+ * -+ * memory_order_acquire: -+ * -+ * Memory accesses after an acquire barrier cannot be moved before the -+ * barrier. Memory accesses before an acquire barrier *can* be moved -+ * after it. -+ * -+ * An atomic_thread_fence with memory_order_acquire does not have a -+ * load operation by itself; it prevents all following memory accesses -+ * from moving prior to preceding loads. -+ * -+ * May not be used with atomic_store_explicit(), as acquire semantics -+ * applies only to atomic loads. -+ * -+ * memory_order_release: -+ * -+ * Memory accesses before a release barrier cannot be moved after the -+ * barrier. Memory accesses after a release barrier *can* be moved -+ * before it. -+ * -+ * An atomic_thread_fence with memory_order_release does not have a -+ * store operation by itself; it prevents all preceding memory accesses -+ * from moving past subsequent stores. -+ * -+ * May not be used with atomic_read_explicit(), as release semantics -+ * applies only to atomic stores. -+ * -+ * memory_order_acq_rel: -+ * -+ * Memory accesses cannot be moved across an acquire-release barrier in -+ * either direction. -+ * -+ * May only be used with atomic read-modify-write operations, as both -+ * load and store operation is required for acquire-release semantics. -+ * -+ * An atomic_thread_fence with memory_order_acq_rel does not have -+ * either load or store operation by itself; it prevents all following -+ * memory accesses from moving prior to preceding loads and all -+ * preceding memory accesses from moving past subsequent stores. -+ * -+ * memory_order_seq_cst: -+ * -+ * Prevents movement of memory accesses like an acquire-release barrier, -+ * but whereas acquire-release synchronizes cooperating threads (using -+ * the same atomic variable), sequential-consistency synchronizes the -+ * whole system, providing a total order for stores on all atomic -+ * variables. -+ * -+ * OVS atomics require the memory_order to be passed as a compile-time constant -+ * value, as some compiler implementations may perform poorly if the memory -+ * order parameter is passed in as a run-time value. -+ * -+ * The following functions insert explicit barriers. Most of the other atomic -+ * functions also include barriers. -+ * -+ * void atomic_thread_fence(memory_order order); -+ * -+ * Inserts a barrier of the specified type. -+ * -+ * For memory_order_relaxed, this is a no-op. -+ * -+ * void atomic_signal_fence(memory_order order); -+ * -+ * Inserts a barrier of the specified type, but only with respect to -+ * signal handlers in the same thread as the barrier. This is -+ * basically a compiler optimization barrier, except for -+ * memory_order_relaxed, which is a no-op. -+ * -+ * -+ * Atomic Operations -+ * ================= -+ * -+ * In this section, A is an atomic type and C is the corresponding non-atomic -+ * type. -+ * -+ * The "store", "exchange", and "compare_exchange" primitives match C11: -+ * -+ * void atomic_store(A *object, C value); -+ * void atomic_store_explicit(A *object, C value, memory_order); -+ * -+ * Atomically stores 'value' into '*object', respecting the given -+ * memory order (or memory_order_seq_cst for atomic_store()). -+ * -+ * bool atomic_compare_exchange_strong(A *object, C *expected, C desired); -+ * bool atomic_compare_exchange_weak(A *object, C *expected, C desired); -+ * bool atomic_compare_exchange_strong_explicit(A *object, C *expected, -+ * C desired, -+ * memory_order success, -+ * memory_order failure); -+ * bool atomic_compare_exchange_weak_explicit(A *object, C *expected, -+ * C desired, -+ * memory_order success, -+ * memory_order failure); -+ * -+ * Atomically loads '*object' and compares it with '*expected' and if -+ * equal, stores 'desired' into '*object' (an atomic read-modify-write -+ * operation) and returns true, and if non-equal, stores the actual -+ * value of '*object' into '*expected' (an atomic load operation) and -+ * returns false. The memory order for the successful case (atomic -+ * read-modify-write operation) is 'success', and for the unsuccessful -+ * case (atomic load operation) 'failure'. 'failure' may not be -+ * stronger than 'success'. -+ * -+ * The weak forms may fail (returning false) also when '*object' equals -+ * '*expected'. The strong form can be implemented by the weak form in -+ * a loop. Some platforms can implement the weak form more -+ * efficiently, so it should be used if the application will need to -+ * loop anyway. -+ * -+ * C atomic_exchange(A *object, C desired); -+ * C atomic_exchange_explicit(A *object, C desired, memory_order); -+ * -+ * Atomically stores 'desired' into '*object', returning the value -+ * previously held. -+ * -+ * The following primitives differ from the C11 ones (and have different names) -+ * because there does not appear to be a way to implement the standard -+ * primitives in standard C: -+ * -+ * void atomic_read(A *src, C *dst); -+ * void atomic_read_explicit(A *src, C *dst, memory_order); -+ * -+ * Atomically loads a value from 'src', writing the value read into -+ * '*dst', respecting the given memory order (or memory_order_seq_cst -+ * for atomic_read()). -+ * -+ * void atomic_add(A *rmw, C arg, C *orig); -+ * void atomic_sub(A *rmw, C arg, C *orig); -+ * void atomic_or(A *rmw, C arg, C *orig); -+ * void atomic_xor(A *rmw, C arg, C *orig); -+ * void atomic_and(A *rmw, C arg, C *orig); -+ * void atomic_add_explicit(A *rmw, C arg, C *orig, memory_order); -+ * void atomic_sub_explicit(A *rmw, C arg, C *orig, memory_order); -+ * void atomic_or_explicit(A *rmw, C arg, C *orig, memory_order); -+ * void atomic_xor_explicit(A *rmw, C arg, C *orig, memory_order); -+ * void atomic_and_explicit(A *rmw, C arg, C *orig, memory_order); -+ * -+ * Atomically applies the given operation, with 'arg' as the second -+ * operand, to '*rmw', and stores the original value of '*rmw' into -+ * '*orig', respecting the given memory order (or memory_order_seq_cst -+ * if none is specified). -+ * -+ * The results are similar to those that would be obtained with +=, -=, -+ * |=, ^=, or |= on non-atomic types. -+ * -+ * -+ * atomic_flag -+ * =========== -+ * -+ * atomic_flag is a typedef for a type with two states, set and clear, that -+ * provides atomic test-and-set functionality. -+ * -+ * -+ * Life Cycle -+ * ---------- -+ * -+ * ATOMIC_FLAG_INIT is an initializer for atomic_flag. The initial state is -+ * "clear". -+ * -+ * An atomic_flag may also be initialized at runtime with atomic_flag_clear(). -+ * -+ * -+ * Operations -+ * ---------- -+ * -+ * The following functions are available. -+ * -+ * bool atomic_flag_test_and_set(atomic_flag *object) -+ * bool atomic_flag_test_and_set_explicit(atomic_flag *object, -+ * memory_order); -+ * -+ * Atomically sets '*object', respecting the given memory order (or -+ * memory_order_seq_cst for atomic_flag_test_and_set()). Returns the -+ * previous value of the flag (false for clear, true for set). -+ * -+ * void atomic_flag_clear(atomic_flag *object); -+ * void atomic_flag_clear_explicit(atomic_flag *object, memory_order); -+ * -+ * Atomically clears '*object', respecting the given memory order (or -+ * memory_order_seq_cst for atomic_flag_clear()). -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "openvswitch/compiler.h" -+#include "internal/util.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define IN_OVS_ATOMIC_H -+ #if __CHECKER__ -+ /* sparse doesn't understand some GCC extensions we use. */ -+ #include "internal/ovs-atomic-pthreads.h" -+ #elif __has_extension(c_atomic) -+ #include "internal/ovs-atomic-clang.h" -+ #elif HAVE_ATOMIC && __cplusplus >= 201103L -+ #include "internal/ovs-atomic-c++.h" -+ #elif HAVE_STDATOMIC_H && !defined(__cplusplus) -+ #include "internal/ovs-atomic-c11.h" -+ #elif __GNUC__ >= 5 && !defined(__cplusplus) -+ #error "GCC 5+ should have " -+ #elif __GNUC__ >= 5 || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 7) -+ #include "internal/ovs-atomic-gcc4.7+.h" -+ #elif __GNUC__ && defined(__x86_64__) -+ #include "internal/ovs-atomic-x86_64.h" -+ #elif __GNUC__ && defined(__i386__) -+ #include "internal/ovs-atomic-i586.h" -+ #elif HAVE_GCC4_ATOMICS -+ #include "internal/ovs-atomic-gcc4+.h" -+ #elif _MSC_VER -+ #include "internal/ovs-atomic-msvc.h" -+ #else -+ /* ovs-atomic-pthreads implementation is provided for portability. -+ * It might be too slow for real use because Open vSwitch is -+ * optimized for platforms where real atomic ops are available. */ -+ #include "internal/ovs-atomic-pthreads.h" -+ #endif -+#undef IN_OVS_ATOMIC_H -+ -+#ifndef OMIT_STANDARD_ATOMIC_TYPES -+typedef ATOMIC(bool) atomic_bool; -+ -+typedef ATOMIC(char) atomic_char; -+typedef ATOMIC(signed char) atomic_schar; -+typedef ATOMIC(unsigned char) atomic_uchar; -+ -+typedef ATOMIC(short) atomic_short; -+typedef ATOMIC(unsigned short) atomic_ushort; -+ -+typedef ATOMIC(int) atomic_int; -+typedef ATOMIC(unsigned int) atomic_uint; -+ -+typedef ATOMIC(long) atomic_long; -+typedef ATOMIC(unsigned long) atomic_ulong; -+ -+typedef ATOMIC(long long) atomic_llong; -+typedef ATOMIC(unsigned long long) atomic_ullong; -+ -+typedef ATOMIC(size_t) atomic_size_t; -+typedef ATOMIC(ptrdiff_t) atomic_ptrdiff_t; -+ -+typedef ATOMIC(intmax_t) atomic_intmax_t; -+typedef ATOMIC(uintmax_t) atomic_uintmax_t; -+ -+typedef ATOMIC(intptr_t) atomic_intptr_t; -+typedef ATOMIC(uintptr_t) atomic_uintptr_t; -+#endif /* !OMIT_STANDARD_ATOMIC_TYPES */ -+ -+/* Nonstandard atomic types. */ -+typedef ATOMIC(uint8_t) atomic_uint8_t; -+typedef ATOMIC(uint16_t) atomic_uint16_t; -+typedef ATOMIC(uint32_t) atomic_uint32_t; -+typedef ATOMIC(uint64_t) atomic_uint64_t; -+ -+typedef ATOMIC(int8_t) atomic_int8_t; -+typedef ATOMIC(int16_t) atomic_int16_t; -+typedef ATOMIC(int32_t) atomic_int32_t; -+typedef ATOMIC(int64_t) atomic_int64_t; -+ -+/* Relaxed atomic operations. -+ * -+ * When an operation on an atomic variable is not expected to synchronize -+ * with operations on other (atomic or non-atomic) variables, no memory -+ * barriers are needed and the relaxed memory ordering can be used. These -+ * macros make such uses less daunting, but not invisible. */ -+#define atomic_store_relaxed(VAR, VALUE) \ -+ atomic_store_explicit(VAR, VALUE, memory_order_relaxed) -+#define atomic_read_relaxed(VAR, DST) \ -+ atomic_read_explicit(VAR, DST, memory_order_relaxed) -+#define atomic_compare_exchange_strong_relaxed(DST, EXP, SRC) \ -+ atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -+ memory_order_relaxed, \ -+ memory_order_relaxed) -+#define atomic_compare_exchange_weak_relaxed(DST, EXP, SRC) \ -+ atomic_compare_exchange_weak_explicit(DST, EXP, SRC, \ -+ memory_order_relaxed, \ -+ memory_order_relaxed) -+#define atomic_add_relaxed(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, ARG, ORIG, memory_order_relaxed) -+#define atomic_sub_relaxed(RMW, ARG, ORIG) \ -+ atomic_sub_explicit(RMW, ARG, ORIG, memory_order_relaxed) -+#define atomic_or_relaxed(RMW, ARG, ORIG) \ -+ atomic_or_explicit(RMW, ARG, ORIG, memory_order_relaxed) -+#define atomic_xor_relaxed(RMW, ARG, ORIG) \ -+ atomic_xor_explicit(RMW, ARG, ORIG, memory_order_relaxed) -+#define atomic_and_relaxed(RMW, ARG, ORIG) \ -+ atomic_and_explicit(RMW, ARG, ORIG, memory_order_relaxed) -+#define atomic_flag_test_and_set_relaxed(FLAG) \ -+ atomic_flag_test_and_set_explicit(FLAG, memory_order_relaxed) -+#define atomic_flag_clear_relaxed(FLAG) \ -+ atomic_flag_clear_explicit(FLAG, memory_order_relaxed) -+ -+/* A simplified atomic count. Does not provide any synchronization with any -+ * other variables. -+ * -+ * Typically a counter is not used to synchronize the state of any other -+ * variables (with the notable exception of reference count, below). -+ * This abstraction releaves the user from the memory order considerations, -+ * and may make the code easier to read. -+ * -+ * We only support the unsigned int counters, as those are the most common. */ -+typedef struct atomic_count { -+ atomic_uint count; -+} atomic_count; -+ -+#define ATOMIC_COUNT_INIT(VALUE) { VALUE } -+ -+static inline void -+atomic_count_init(atomic_count *count, unsigned int value) -+{ -+ atomic_init(&count->count, value); -+} -+ -+static inline unsigned int -+atomic_count_inc(atomic_count *count) -+{ -+ unsigned int old; -+ -+ atomic_add_relaxed(&count->count, 1u, &old); -+ -+ return old; -+} -+ -+static inline unsigned int -+atomic_count_dec(atomic_count *count) -+{ -+ unsigned int old; -+ -+ atomic_sub_relaxed(&count->count, 1u, &old); -+ -+ return old; -+} -+ -+static inline unsigned int -+atomic_count_get(atomic_count *count) -+{ -+ unsigned int value; -+ -+ atomic_read_relaxed(&count->count, &value); -+ -+ return value; -+} -+ -+static inline void -+atomic_count_set(atomic_count *count, unsigned int value) -+{ -+ atomic_store_relaxed(&count->count, value); -+} -+ -+static inline uint64_t -+atomic_count_inc64(atomic_uint64_t *counter) -+{ -+ uint64_t old; -+ -+ atomic_add_relaxed(counter, 1ull, &old); -+ -+ return old; -+} -+ -+static inline uint64_t -+atomic_count_dec64(atomic_uint64_t *counter) -+{ -+ uint64_t old; -+ -+ atomic_sub_relaxed(counter, 1ull, &old); -+ -+ return old; -+} -+ -+static inline uint64_t -+atomic_count_get64(atomic_uint64_t *counter) -+{ -+ uint64_t value; -+ -+ atomic_read_relaxed(counter, &value); -+ -+ return value; -+} -+ -+static inline void -+atomic_count_set64(atomic_uint64_t *counter, uint64_t value) -+{ -+ atomic_store_relaxed(counter, value); -+} -+ -+/* Reference count. */ -+struct ovs_refcount { -+ atomic_uint count; -+}; -+ -+/* Initializes 'refcount'. The reference count is initially 1. */ -+static inline void -+ovs_refcount_init(struct ovs_refcount *refcount) -+{ -+ atomic_init(&refcount->count, 1u); -+} -+ -+/* Increments 'refcount'. -+ * -+ * Does not provide a memory barrier, as the calling thread must have -+ * protected access to the object already. */ -+static inline void -+ovs_refcount_ref(struct ovs_refcount *refcount) -+{ -+ unsigned int old_refcount; -+ -+ atomic_add_explicit(&refcount->count, 1u, &old_refcount, -+ memory_order_relaxed); -+ ovs_assert(old_refcount > 0); -+} -+ -+/* Decrements 'refcount' and returns the previous reference count. Often used -+ * in this form: -+ * -+ * if (ovs_refcount_unref(&object->ref_cnt) == 1) { -+ * ...uninitialize object... -+ * free(object); -+ * } -+ * -+ * Provides a release barrier making the preceding loads and stores to not be -+ * reordered after the unref, and in case of the last reference provides also -+ * an acquire barrier to keep all the following uninitialization from being -+ * reordered before the atomic decrement operation. Together these synchronize -+ * any concurrent unref operations between each other. */ -+static inline unsigned int -+ovs_refcount_unref(struct ovs_refcount *refcount) -+{ -+ unsigned int old_refcount; -+ -+ atomic_sub_explicit(&refcount->count, 1u, &old_refcount, -+ memory_order_release); -+ ovs_assert(old_refcount > 0); -+ if (old_refcount == 1) { -+ /* 'memory_order_release' above means that there are no (reordered) -+ * accesses to the protected object from any thread at this point. -+ * An acquire barrier is needed to keep all subsequent access to the -+ * object's memory from being reordered before the atomic operation -+ * above. */ -+ atomic_thread_fence(memory_order_acquire); -+ } -+ return old_refcount; -+} -+ -+/* Reads and returns 'refcount_''s current reference count. -+ * -+ * Does not provide a memory barrier. -+ * -+ * Rarely useful. */ -+static inline unsigned int -+ovs_refcount_read(const struct ovs_refcount *refcount_) -+{ -+ struct ovs_refcount *refcount -+ = CONST_CAST(struct ovs_refcount *, refcount_); -+ unsigned int count; -+ -+ atomic_read_explicit(&refcount->count, &count, memory_order_relaxed); -+ return count; -+} -+ -+/* Increments 'refcount', but only if it is non-zero. -+ * -+ * This may only be called for an object which is RCU protected during -+ * this call. This implies that its possible destruction is postponed -+ * until all current RCU threads quiesce. -+ * -+ * Returns false if the refcount was zero. In this case the object may -+ * be safely accessed until the current thread quiesces, but no additional -+ * references to the object may be taken. -+ * -+ * Does not provide a memory barrier, as the calling thread must have -+ * RCU protected access to the object already. -+ * -+ * It is critical that we never increment a zero refcount to a -+ * non-zero value, as whenever a refcount reaches the zero value, the -+ * protected object may be irrevocably scheduled for deletion. */ -+static inline bool -+ovs_refcount_try_ref_rcu(struct ovs_refcount *refcount) -+{ -+ unsigned int count; -+ -+ atomic_read_explicit(&refcount->count, &count, memory_order_relaxed); -+ do { -+ if (count == 0) { -+ return false; -+ } -+ } while (!atomic_compare_exchange_weak_explicit(&refcount->count, &count, -+ count + 1, -+ memory_order_relaxed, -+ memory_order_relaxed)); -+ return true; -+} -+ -+/* Decrements 'refcount' and returns the previous reference count. To -+ * be used only when a memory barrier is already provided for the -+ * protected object independently. -+ * -+ * For example: -+ * -+ * if (ovs_refcount_unref_relaxed(&object->ref_cnt) == 1) { -+ * ovsrcu_postpone(destructor_function, object); -+ * } -+ * -+ * Here RCU quiescing already provides a full memory barrier. No additional -+ * barriers are needed here. -+ * -+ * Or: -+ * -+ * if (stp && ovs_refcount_unref_relaxed(&stp->ref_cnt) == 1) { -+ * ovs_mutex_lock(&mutex); -+ * ovs_list_remove(&stp->node); -+ * ovs_mutex_unlock(&mutex); -+ * free(stp->name); -+ * free(stp); -+ * } -+ * -+ * Here a mutex is used to guard access to all of 'stp' apart from -+ * 'ref_cnt'. Hence all changes to 'stp' by other threads must be -+ * visible when we get the mutex, and no access after the unlock can -+ * be reordered to happen prior the lock operation. No additional -+ * barriers are needed here. -+ */ -+static inline unsigned int -+ovs_refcount_unref_relaxed(struct ovs_refcount *refcount) -+{ -+ unsigned int old_refcount; -+ -+ atomic_sub_explicit(&refcount->count, 1u, &old_refcount, -+ memory_order_relaxed); -+ ovs_assert(old_refcount > 0); -+ return old_refcount; -+} -+ -+#ifdef __cplusplus -+} // extern "C" -+#endif -+ -+#endif /* ovs-atomic.h */ -Index: openvswitch-2.17.2/lib/ovs-numa.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-numa.h -+++ /dev/null -@@ -1,76 +0,0 @@ --/* -- * Copyright (c) 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVS_NUMA_H --#define OVS_NUMA_H 1 -- --#include --#include -- --#include "openvswitch/compiler.h" --#include "openvswitch/hmap.h" -- --#define OVS_CORE_UNSPEC INT_MAX --#define OVS_NUMA_UNSPEC INT_MAX -- --#define MAX_NUMA_NODES 128 -- --/* Dump of a list of 'struct ovs_numa_info'. */ --struct ovs_numa_dump { -- struct hmap cores; -- struct hmap numas; --}; -- --/* A numa_id - core_id pair. */ --struct ovs_numa_info_core { -- struct hmap_node hmap_node; -- int numa_id; -- unsigned core_id; --}; -- --/* A numa node. */ --struct ovs_numa_info_numa { -- struct hmap_node hmap_node; -- int numa_id; -- size_t n_cores; --}; -- --void ovs_numa_init(void); --void ovs_numa_set_dummy(const char *config); --bool ovs_numa_numa_id_is_valid(int numa_id); --bool ovs_numa_core_id_is_valid(unsigned core_id); --int ovs_numa_get_n_numas(void); --int ovs_numa_get_n_cores(void); --int ovs_numa_get_numa_id(unsigned core_id); --int ovs_numa_get_n_cores_on_numa(int numa_id); --struct ovs_numa_dump *ovs_numa_dump_cores_on_numa(int numa_id); --struct ovs_numa_dump *ovs_numa_dump_cores_with_cmask(const char *cmask); --struct ovs_numa_dump *ovs_numa_dump_n_cores_per_numa(int n); --bool ovs_numa_dump_contains_core(const struct ovs_numa_dump *, -- int numa_id, unsigned core_id); --size_t ovs_numa_dump_count(const struct ovs_numa_dump *); --struct ovs_numa_dump * ovs_numa_thread_getaffinity_dump(void); --int ovs_numa_thread_setaffinity_dump(const struct ovs_numa_dump *); --void ovs_numa_dump_destroy(struct ovs_numa_dump *); --int ovs_numa_thread_setaffinity_core(unsigned core_id); -- --#define FOR_EACH_CORE_ON_DUMP(ITER, DUMP) \ -- HMAP_FOR_EACH (ITER, hmap_node, &(DUMP)->cores) -- --#define FOR_EACH_NUMA_ON_DUMP(ITER, DUMP) \ -- HMAP_FOR_EACH (ITER, hmap_node, &(DUMP)->numas) -- --#endif /* ovs-numa.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovs-numa.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovs-numa.h -@@ -0,0 +1,84 @@ -+/* -+ * Copyright (c) 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVS_NUMA_H -+#define OVS_NUMA_H 1 -+ -+#include -+#include -+ -+#include "openvswitch/compiler.h" -+#include "openvswitch/hmap.h" -+ -+#define OVS_CORE_UNSPEC INT_MAX -+#define OVS_NUMA_UNSPEC INT_MAX -+ -+#define MAX_NUMA_NODES 128 -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Dump of a list of 'struct ovs_numa_info'. */ -+struct ovs_numa_dump { -+ struct hmap cores; -+ struct hmap numas; -+}; -+ -+/* A numa_id - core_id pair. */ -+struct ovs_numa_info_core { -+ struct hmap_node hmap_node; -+ int numa_id; -+ unsigned core_id; -+}; -+ -+/* A numa node. */ -+struct ovs_numa_info_numa { -+ struct hmap_node hmap_node; -+ int numa_id; -+ size_t n_cores; -+}; -+ -+void ovs_numa_init(void); -+void ovs_numa_set_dummy(const char *config); -+bool ovs_numa_numa_id_is_valid(int numa_id); -+bool ovs_numa_core_id_is_valid(unsigned core_id); -+int ovs_numa_get_n_numas(void); -+int ovs_numa_get_n_cores(void); -+int ovs_numa_get_numa_id(unsigned core_id); -+int ovs_numa_get_n_cores_on_numa(int numa_id); -+struct ovs_numa_dump *ovs_numa_dump_cores_on_numa(int numa_id); -+struct ovs_numa_dump *ovs_numa_dump_cores_with_cmask(const char *cmask); -+struct ovs_numa_dump *ovs_numa_dump_n_cores_per_numa(int n); -+bool ovs_numa_dump_contains_core(const struct ovs_numa_dump *, -+ int numa_id, unsigned core_id); -+size_t ovs_numa_dump_count(const struct ovs_numa_dump *); -+struct ovs_numa_dump * ovs_numa_thread_getaffinity_dump(void); -+int ovs_numa_thread_setaffinity_dump(const struct ovs_numa_dump *); -+void ovs_numa_dump_destroy(struct ovs_numa_dump *); -+int ovs_numa_thread_setaffinity_core(unsigned core_id); -+ -+#define FOR_EACH_CORE_ON_DUMP(ITER, DUMP) \ -+ HMAP_FOR_EACH (ITER, hmap_node, &(DUMP)->cores) -+ -+#define FOR_EACH_NUMA_ON_DUMP(ITER, DUMP) \ -+ HMAP_FOR_EACH (ITER, hmap_node, &(DUMP)->numas) -+ -+#ifdef __cplusplus -+} // extern "C" -+#endif -+ -+#endif /* ovs-numa.h */ -Index: openvswitch-2.17.2/lib/ovs-rcu.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-rcu.h -+++ /dev/null -@@ -1,328 +0,0 @@ --/* -- * Copyright (c) 2014, 2015, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVS_RCU_H --#define OVS_RCU_H 1 -- --/* Read-Copy-Update (RCU) -- * ====================== -- * -- * Introduction -- * ------------ -- * -- * Atomic pointer access makes it pretty easy to implement lock-free -- * algorithms. There is one big problem, though: when a writer updates a -- * pointer to point to a new data structure, some thread might be reading the -- * old version, and there's no convenient way to free the old version when all -- * threads are done with the old version. -- * -- * The function ovsrcu_postpone() solves that problem. The function pointer -- * passed in as its argument is called only after all threads are done with old -- * versions of data structures. The function callback frees an old version of -- * data no longer in use. This technique is called "read-copy-update", or RCU -- * for short. -- * -- * -- * Details -- * ------- -- * -- * A "quiescent state" is a time at which a thread holds no pointers to memory -- * that is managed by RCU; that is, when the thread is known not to reference -- * memory that might be an old version of some object freed via RCU. For -- * example, poll_block() includes a quiescent state. -- * -- * The following functions manage the recognition of quiescent states: -- * -- * void ovsrcu_quiesce(void) -- * -- * Recognizes a momentary quiescent state in the current thread. -- * -- * void ovsrcu_quiesce_start(void) -- * void ovsrcu_quiesce_end(void) -- * -- * Brackets a time period during which the current thread is quiescent. -- * -- * A newly created thread is initially active, not quiescent. When a process -- * becomes multithreaded, the main thread becomes active, not quiescent. -- * -- * When a quiescient state has occurred in every thread, we say that a "grace -- * period" has occurred. Following a grace period, all of the callbacks -- * postponed before the start of the grace period MAY be invoked. OVS takes -- * care of this automatically through the RCU mechanism: while a process still -- * has only a single thread, it invokes the postponed callbacks directly from -- * ovsrcu_quiesce() and ovsrcu_quiesce_start(); after additional threads have -- * been created, it creates an extra helper thread to invoke callbacks. -- * -- * Please note that while a postponed function call is guaranteed to happen -- * after the next time all participating threads have quiesced at least once, -- * there is no quarantee that all postponed functions are called as early as -- * possible, or that the functions postponed by different threads would be -- * called in the order the registrations took place. In particular, even if -- * two threads provably postpone a function each in a specific order, the -- * postponed functions may still be called in the opposite order, depending on -- * the timing of when the threads call ovsrcu_quiesce(), how many functions -- * they postpone, and when the ovs-rcu thread happens to grab the functions to -- * be called. -- * -- * All functions postponed by a single thread are guaranteed to execute in the -- * order they were postponed, however. -- * -- * Usage -- * ----- -- * -- * Use OVSRCU_TYPE(TYPE) to declare a pointer to RCU-protected data, e.g. the -- * following declares an RCU-protected "struct flow *" named flowp: -- * -- * OVSRCU_TYPE(struct flow *) flowp; -- * -- * Use ovsrcu_get(TYPE, VAR) to read an RCU-protected pointer, e.g. to read the -- * pointer variable declared above: -- * -- * struct flow *flow = ovsrcu_get(struct flow *, &flowp); -- * -- * If the pointer variable is currently protected against change (because -- * the current thread holds a mutex that protects it), ovsrcu_get_protected() -- * may be used instead. Only on the Alpha architecture is this likely to -- * generate different code, but it may be useful documentation. -- * -- * (With GNU C or Clang, you get a compiler error if TYPE is wrong; other -- * compilers will merrily carry along accepting the wrong type.) -- * -- * Use ovsrcu_set() to write an RCU-protected pointer and ovsrcu_postpone() to -- * free the previous data. ovsrcu_set_hidden() can be used on RCU protected -- * data not visible to any readers yet, but will be made visible by a later -- * ovsrcu_set(). ovsrcu_init() can be used to initialize RCU pointers when -- * no readers are yet executing. If more than one thread can write the -- * pointer, then some form of external synchronization, e.g. a mutex, is -- * needed to prevent writers from interfering with one another. For example, -- * to write the pointer variable declared above while safely freeing the old -- * value: -- * -- * static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; -- * -- * OVSRCU_TYPE(struct flow *) flowp; -- * -- * void -- * change_flow(struct flow *new_flow) -- * { -- * ovs_mutex_lock(&mutex); -- * ovsrcu_postpone(free, -- * ovsrcu_get_protected(struct flow *, &flowp)); -- * ovsrcu_set(&flowp, new_flow); -- * ovs_mutex_unlock(&mutex); -- * } -- * -- * In some rare cases an object may not be addressable with a pointer, but only -- * through an array index (e.g. because it's provided by another library). It -- * is still possible to have RCU semantics by using the ovsrcu_index type. -- * -- * static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; -- * -- * ovsrcu_index port_id; -- * -- * void tx() -- * { -- * int id = ovsrcu_index_get(&port_id); -- * if (id == -1) { -- * return; -- * } -- * port_tx(id); -- * } -- * -- * void delete() -- * { -- * int id; -- * -- * ovs_mutex_lock(&mutex); -- * id = ovsrcu_index_get_protected(&port_id); -- * ovsrcu_index_set(&port_id, -1); -- * ovs_mutex_unlock(&mutex); -- * -- * ovsrcu_synchronize(); -- * port_delete(id); -- * } -- * -- * Use ovsrcu_barrier() to wait for all the outstanding RCU callbacks to -- * finish. This is useful when you have to destroy some resources however -- * these resources are referenced in the outstanding RCU callbacks. -- * -- * void rcu_cb(void *A) { -- * do_something(A); -- * } -- * -- * void destroy_A() { -- * ovsrcu_postpone(rcu_cb, A); // will use A later -- * ovsrcu_barrier(); // wait for rcu_cb done -- * do_destroy_A(); // free A -- * } -- */ -- --#include "openvswitch/compiler.h" --#include "ovs-atomic.h" -- --#if __GNUC__ --#define OVSRCU_TYPE(TYPE) struct { ATOMIC(TYPE) p; } --#define OVSRCU_INITIALIZER(VALUE) { ATOMIC_VAR_INIT(VALUE) } --#define ovsrcu_get__(TYPE, VAR, ORDER) \ -- ({ \ -- TYPE value__; \ -- typeof(VAR) ovsrcu_var = (VAR); \ -- \ -- atomic_read_explicit(CONST_CAST(ATOMIC(TYPE) *, &ovsrcu_var->p), \ -- &value__, ORDER); \ -- \ -- value__; \ -- }) --#define ovsrcu_get(TYPE, VAR) \ -- ovsrcu_get__(TYPE, VAR, memory_order_consume) --#define ovsrcu_get_protected(TYPE, VAR) \ -- ovsrcu_get__(TYPE, VAR, memory_order_relaxed) -- --/* 'VALUE' may be an atomic operation, which must be evaluated before -- * any of the body of the atomic_store_explicit. Since the type of -- * 'VAR' is not fixed, we cannot use an inline function to get -- * function semantics for this. */ --#define ovsrcu_set__(VAR, VALUE, ORDER) \ -- ({ \ -- typeof(VAR) ovsrcu_var = (VAR); \ -- typeof(VALUE) ovsrcu_value = (VALUE); \ -- memory_order ovsrcu_order = (ORDER); \ -- \ -- atomic_store_explicit(&ovsrcu_var->p, ovsrcu_value, ovsrcu_order); \ -- (void *) 0; \ -- }) --#else /* not GNU C */ --struct ovsrcu_pointer { ATOMIC(void *) p; }; --#define OVSRCU_TYPE(TYPE) struct ovsrcu_pointer --#define OVSRCU_INITIALIZER(VALUE) { ATOMIC_VAR_INIT(VALUE) } --static inline void * --ovsrcu_get__(const struct ovsrcu_pointer *pointer, memory_order order) --{ -- void *value; -- atomic_read_explicit(&CONST_CAST(struct ovsrcu_pointer *, pointer)->p, -- &value, order); -- return value; --} --#define ovsrcu_get(TYPE, VAR) \ -- CONST_CAST(TYPE, ovsrcu_get__(VAR, memory_order_consume)) --#define ovsrcu_get_protected(TYPE, VAR) \ -- CONST_CAST(TYPE, ovsrcu_get__(VAR, memory_order_relaxed)) -- --static inline void ovsrcu_set__(struct ovsrcu_pointer *pointer, -- const void *value, -- memory_order order) --{ -- atomic_store_explicit(&pointer->p, CONST_CAST(void *, value), order); --} --#endif -- --/* Writes VALUE to the RCU-protected pointer whose address is VAR. -- * -- * Users require external synchronization (e.g. a mutex). See "Usage" above -- * for an example. */ --#define ovsrcu_set(VAR, VALUE) \ -- ovsrcu_set__(VAR, VALUE, memory_order_release) -- --/* This can be used for initializing RCU pointers before any readers can -- * see them. A later ovsrcu_set() needs to make the bigger structure this -- * is part of visible to the readers. */ --#define ovsrcu_set_hidden(VAR, VALUE) \ -- ovsrcu_set__(VAR, VALUE, memory_order_relaxed) -- --/* This can be used for initializing RCU pointers before any readers are -- * executing. */ --#define ovsrcu_init(VAR, VALUE) atomic_init(&(VAR)->p, VALUE) -- --/* Calls FUNCTION passing ARG as its pointer-type argument following the next -- * grace period. See "Usage" above for an example. */ --void ovsrcu_postpone__(void (*function)(void *aux), void *aux); --#define ovsrcu_postpone(FUNCTION, ARG) \ -- (/* Verify that ARG is appropriate for FUNCTION. */ \ -- (void) sizeof((FUNCTION)(ARG), 1), \ -- /* Verify that ARG is a pointer type. */ \ -- (void) sizeof(*(ARG)), \ -- ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG)) -- --/* An array index protected by RCU semantics. This is an easier alternative to -- * an RCU protected pointer to a malloc'd int. */ --typedef struct { atomic_int v; } ovsrcu_index; -- --static inline int ovsrcu_index_get__(const ovsrcu_index *i, memory_order order) --{ -- int ret; -- atomic_read_explicit(CONST_CAST(atomic_int *, &i->v), &ret, order); -- return ret; --} -- --/* Returns the index contained in 'i'. The returned value can be used until -- * the next grace period. */ --static inline int ovsrcu_index_get(const ovsrcu_index *i) --{ -- return ovsrcu_index_get__(i, memory_order_consume); --} -- --/* Returns the index contained in 'i'. This is an alternative to -- * ovsrcu_index_get() that can be used when there's no possible concurrent -- * writer. */ --static inline int ovsrcu_index_get_protected(const ovsrcu_index *i) --{ -- return ovsrcu_index_get__(i, memory_order_relaxed); --} -- --static inline void ovsrcu_index_set__(ovsrcu_index *i, int value, -- memory_order order) --{ -- atomic_store_explicit(&i->v, value, order); --} -- --/* Writes the index 'value' in 'i'. The previous value of 'i' may still be -- * used by readers until the next grace period. */ --static inline void ovsrcu_index_set(ovsrcu_index *i, int value) --{ -- ovsrcu_index_set__(i, value, memory_order_release); --} -- --/* Writes the index 'value' in 'i'. This is an alternative to -- * ovsrcu_index_set() that can be used when there's no possible concurrent -- * reader. */ --static inline void ovsrcu_index_set_hidden(ovsrcu_index *i, int value) --{ -- ovsrcu_index_set__(i, value, memory_order_relaxed); --} -- --/* Initializes 'i' with 'value'. This is safe to call as long as there are no -- * concurrent readers. */ --static inline void ovsrcu_index_init(ovsrcu_index *i, int value) --{ -- atomic_init(&i->v, value); --} -- --/* Quiescent states. */ --void ovsrcu_quiesce_start(void); --void ovsrcu_quiesce_end(void); --void ovsrcu_quiesce(void); --int ovsrcu_try_quiesce(void); --bool ovsrcu_is_quiescent(void); -- --/* Synchronization. Waits for all non-quiescent threads to quiesce at least -- * once. This can block for a relatively long time. */ --void ovsrcu_synchronize(void); -- --void ovsrcu_exit(void); -- --void ovsrcu_barrier(void); -- --#endif /* ovs-rcu.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovs-rcu.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovs-rcu.h -@@ -0,0 +1,336 @@ -+/* -+ * Copyright (c) 2014, 2015, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVS_RCU_H -+#define OVS_RCU_H 1 -+ -+/* Read-Copy-Update (RCU) -+ * ====================== -+ * -+ * Introduction -+ * ------------ -+ * -+ * Atomic pointer access makes it pretty easy to implement lock-free -+ * algorithms. There is one big problem, though: when a writer updates a -+ * pointer to point to a new data structure, some thread might be reading the -+ * old version, and there's no convenient way to free the old version when all -+ * threads are done with the old version. -+ * -+ * The function ovsrcu_postpone() solves that problem. The function pointer -+ * passed in as its argument is called only after all threads are done with old -+ * versions of data structures. The function callback frees an old version of -+ * data no longer in use. This technique is called "read-copy-update", or RCU -+ * for short. -+ * -+ * -+ * Details -+ * ------- -+ * -+ * A "quiescent state" is a time at which a thread holds no pointers to memory -+ * that is managed by RCU; that is, when the thread is known not to reference -+ * memory that might be an old version of some object freed via RCU. For -+ * example, poll_block() includes a quiescent state. -+ * -+ * The following functions manage the recognition of quiescent states: -+ * -+ * void ovsrcu_quiesce(void) -+ * -+ * Recognizes a momentary quiescent state in the current thread. -+ * -+ * void ovsrcu_quiesce_start(void) -+ * void ovsrcu_quiesce_end(void) -+ * -+ * Brackets a time period during which the current thread is quiescent. -+ * -+ * A newly created thread is initially active, not quiescent. When a process -+ * becomes multithreaded, the main thread becomes active, not quiescent. -+ * -+ * When a quiescient state has occurred in every thread, we say that a "grace -+ * period" has occurred. Following a grace period, all of the callbacks -+ * postponed before the start of the grace period MAY be invoked. OVS takes -+ * care of this automatically through the RCU mechanism: while a process still -+ * has only a single thread, it invokes the postponed callbacks directly from -+ * ovsrcu_quiesce() and ovsrcu_quiesce_start(); after additional threads have -+ * been created, it creates an extra helper thread to invoke callbacks. -+ * -+ * Please note that while a postponed function call is guaranteed to happen -+ * after the next time all participating threads have quiesced at least once, -+ * there is no quarantee that all postponed functions are called as early as -+ * possible, or that the functions postponed by different threads would be -+ * called in the order the registrations took place. In particular, even if -+ * two threads provably postpone a function each in a specific order, the -+ * postponed functions may still be called in the opposite order, depending on -+ * the timing of when the threads call ovsrcu_quiesce(), how many functions -+ * they postpone, and when the ovs-rcu thread happens to grab the functions to -+ * be called. -+ * -+ * All functions postponed by a single thread are guaranteed to execute in the -+ * order they were postponed, however. -+ * -+ * Usage -+ * ----- -+ * -+ * Use OVSRCU_TYPE(TYPE) to declare a pointer to RCU-protected data, e.g. the -+ * following declares an RCU-protected "struct flow *" named flowp: -+ * -+ * OVSRCU_TYPE(struct flow *) flowp; -+ * -+ * Use ovsrcu_get(TYPE, VAR) to read an RCU-protected pointer, e.g. to read the -+ * pointer variable declared above: -+ * -+ * struct flow *flow = ovsrcu_get(struct flow *, &flowp); -+ * -+ * If the pointer variable is currently protected against change (because -+ * the current thread holds a mutex that protects it), ovsrcu_get_protected() -+ * may be used instead. Only on the Alpha architecture is this likely to -+ * generate different code, but it may be useful documentation. -+ * -+ * (With GNU C or Clang, you get a compiler error if TYPE is wrong; other -+ * compilers will merrily carry along accepting the wrong type.) -+ * -+ * Use ovsrcu_set() to write an RCU-protected pointer and ovsrcu_postpone() to -+ * free the previous data. ovsrcu_set_hidden() can be used on RCU protected -+ * data not visible to any readers yet, but will be made visible by a later -+ * ovsrcu_set(). ovsrcu_init() can be used to initialize RCU pointers when -+ * no readers are yet executing. If more than one thread can write the -+ * pointer, then some form of external synchronization, e.g. a mutex, is -+ * needed to prevent writers from interfering with one another. For example, -+ * to write the pointer variable declared above while safely freeing the old -+ * value: -+ * -+ * static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; -+ * -+ * OVSRCU_TYPE(struct flow *) flowp; -+ * -+ * void -+ * change_flow(struct flow *new_flow) -+ * { -+ * ovs_mutex_lock(&mutex); -+ * ovsrcu_postpone(free, -+ * ovsrcu_get_protected(struct flow *, &flowp)); -+ * ovsrcu_set(&flowp, new_flow); -+ * ovs_mutex_unlock(&mutex); -+ * } -+ * -+ * In some rare cases an object may not be addressable with a pointer, but only -+ * through an array index (e.g. because it's provided by another library). It -+ * is still possible to have RCU semantics by using the ovsrcu_index type. -+ * -+ * static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; -+ * -+ * ovsrcu_index port_id; -+ * -+ * void tx() -+ * { -+ * int id = ovsrcu_index_get(&port_id); -+ * if (id == -1) { -+ * return; -+ * } -+ * port_tx(id); -+ * } -+ * -+ * void delete() -+ * { -+ * int id; -+ * -+ * ovs_mutex_lock(&mutex); -+ * id = ovsrcu_index_get_protected(&port_id); -+ * ovsrcu_index_set(&port_id, -1); -+ * ovs_mutex_unlock(&mutex); -+ * -+ * ovsrcu_synchronize(); -+ * port_delete(id); -+ * } -+ * -+ * Use ovsrcu_barrier() to wait for all the outstanding RCU callbacks to -+ * finish. This is useful when you have to destroy some resources however -+ * these resources are referenced in the outstanding RCU callbacks. -+ * -+ * void rcu_cb(void *A) { -+ * do_something(A); -+ * } -+ * -+ * void destroy_A() { -+ * ovsrcu_postpone(rcu_cb, A); // will use A later -+ * ovsrcu_barrier(); // wait for rcu_cb done -+ * do_destroy_A(); // free A -+ * } -+ */ -+ -+#include "openvswitch/compiler.h" -+#include "openvswitch/ovs-atomic.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#if __GNUC__ -+#define OVSRCU_TYPE(TYPE) struct { ATOMIC(TYPE) p; } -+#define OVSRCU_INITIALIZER(VALUE) { ATOMIC_VAR_INIT(VALUE) } -+#define ovsrcu_get__(TYPE, VAR, ORDER) \ -+ ({ \ -+ TYPE value__; \ -+ typeof(VAR) ovsrcu_var = (VAR); \ -+ \ -+ atomic_read_explicit(CONST_CAST(ATOMIC(TYPE) *, &ovsrcu_var->p), \ -+ &value__, ORDER); \ -+ \ -+ value__; \ -+ }) -+#define ovsrcu_get(TYPE, VAR) \ -+ ovsrcu_get__(TYPE, VAR, memory_order_consume) -+#define ovsrcu_get_protected(TYPE, VAR) \ -+ ovsrcu_get__(TYPE, VAR, memory_order_relaxed) -+ -+/* 'VALUE' may be an atomic operation, which must be evaluated before -+ * any of the body of the atomic_store_explicit. Since the type of -+ * 'VAR' is not fixed, we cannot use an inline function to get -+ * function semantics for this. */ -+#define ovsrcu_set__(VAR, VALUE, ORDER) \ -+ ({ \ -+ typeof(VAR) ovsrcu_var = (VAR); \ -+ typeof(VALUE) ovsrcu_value = (VALUE); \ -+ memory_order ovsrcu_order = (ORDER); \ -+ \ -+ atomic_store_explicit(&ovsrcu_var->p, ovsrcu_value, ovsrcu_order); \ -+ (void *) 0; \ -+ }) -+#else /* not GNU C */ -+struct ovsrcu_pointer { ATOMIC(void *) p; }; -+#define OVSRCU_TYPE(TYPE) struct ovsrcu_pointer -+#define OVSRCU_INITIALIZER(VALUE) { ATOMIC_VAR_INIT(VALUE) } -+static inline void * -+ovsrcu_get__(const struct ovsrcu_pointer *pointer, memory_order order) -+{ -+ void *value; -+ atomic_read_explicit(&CONST_CAST(struct ovsrcu_pointer *, pointer)->p, -+ &value, order); -+ return value; -+} -+#define ovsrcu_get(TYPE, VAR) \ -+ CONST_CAST(TYPE, ovsrcu_get__(VAR, memory_order_consume)) -+#define ovsrcu_get_protected(TYPE, VAR) \ -+ CONST_CAST(TYPE, ovsrcu_get__(VAR, memory_order_relaxed)) -+ -+static inline void ovsrcu_set__(struct ovsrcu_pointer *pointer, -+ const void *value, -+ memory_order order) -+{ -+ atomic_store_explicit(&pointer->p, CONST_CAST(void *, value), order); -+} -+#endif -+ -+/* Writes VALUE to the RCU-protected pointer whose address is VAR. -+ * -+ * Users require external synchronization (e.g. a mutex). See "Usage" above -+ * for an example. */ -+#define ovsrcu_set(VAR, VALUE) \ -+ ovsrcu_set__(VAR, VALUE, memory_order_release) -+ -+/* This can be used for initializing RCU pointers before any readers can -+ * see them. A later ovsrcu_set() needs to make the bigger structure this -+ * is part of visible to the readers. */ -+#define ovsrcu_set_hidden(VAR, VALUE) \ -+ ovsrcu_set__(VAR, VALUE, memory_order_relaxed) -+ -+/* This can be used for initializing RCU pointers before any readers are -+ * executing. */ -+#define ovsrcu_init(VAR, VALUE) atomic_init(&(VAR)->p, VALUE) -+ -+/* Calls FUNCTION passing ARG as its pointer-type argument following the next -+ * grace period. See "Usage" above for an example. */ -+void ovsrcu_postpone__(void (*function)(void *aux), void *aux); -+#define ovsrcu_postpone(FUNCTION, ARG) \ -+ (/* Verify that ARG is appropriate for FUNCTION. */ \ -+ (void) sizeof((FUNCTION)(ARG), 1), \ -+ /* Verify that ARG is a pointer type. */ \ -+ (void) sizeof(*(ARG)), \ -+ ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG)) -+ -+/* An array index protected by RCU semantics. This is an easier alternative to -+ * an RCU protected pointer to a malloc'd int. */ -+typedef struct { atomic_int v; } ovsrcu_index; -+ -+static inline int ovsrcu_index_get__(const ovsrcu_index *i, memory_order order) -+{ -+ int ret; -+ atomic_read_explicit(CONST_CAST(atomic_int *, &i->v), &ret, order); -+ return ret; -+} -+ -+/* Returns the index contained in 'i'. The returned value can be used until -+ * the next grace period. */ -+static inline int ovsrcu_index_get(const ovsrcu_index *i) -+{ -+ return ovsrcu_index_get__(i, memory_order_consume); -+} -+ -+/* Returns the index contained in 'i'. This is an alternative to -+ * ovsrcu_index_get() that can be used when there's no possible concurrent -+ * writer. */ -+static inline int ovsrcu_index_get_protected(const ovsrcu_index *i) -+{ -+ return ovsrcu_index_get__(i, memory_order_relaxed); -+} -+ -+static inline void ovsrcu_index_set__(ovsrcu_index *i, int value, -+ memory_order order) -+{ -+ atomic_store_explicit(&i->v, value, order); -+} -+ -+/* Writes the index 'value' in 'i'. The previous value of 'i' may still be -+ * used by readers until the next grace period. */ -+static inline void ovsrcu_index_set(ovsrcu_index *i, int value) -+{ -+ ovsrcu_index_set__(i, value, memory_order_release); -+} -+ -+/* Writes the index 'value' in 'i'. This is an alternative to -+ * ovsrcu_index_set() that can be used when there's no possible concurrent -+ * reader. */ -+static inline void ovsrcu_index_set_hidden(ovsrcu_index *i, int value) -+{ -+ ovsrcu_index_set__(i, value, memory_order_relaxed); -+} -+ -+/* Initializes 'i' with 'value'. This is safe to call as long as there are no -+ * concurrent readers. */ -+static inline void ovsrcu_index_init(ovsrcu_index *i, int value) -+{ -+ atomic_init(&i->v, value); -+} -+ -+/* Quiescent states. */ -+void ovsrcu_quiesce_start(void); -+void ovsrcu_quiesce_end(void); -+void ovsrcu_quiesce(void); -+int ovsrcu_try_quiesce(void); -+bool ovsrcu_is_quiescent(void); -+ -+/* Synchronization. Waits for all non-quiescent threads to quiesce at least -+ * once. This can block for a relatively long time. */ -+void ovsrcu_synchronize(void); -+ -+void ovsrcu_exit(void); -+ -+void ovsrcu_barrier(void); -+ -+#ifdef __cplusplus -+} // extern "C" -+#endif -+ -+#endif /* ovs-rcu.h */ -Index: openvswitch-2.17.2/lib/ovs-thread.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-thread.h -+++ /dev/null -@@ -1,527 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVS_THREAD_H --#define OVS_THREAD_H 1 -- --#include --#include --#include --#include "ovs-atomic.h" --#include "ovs-rcu.h" --#include "openvswitch/thread.h" --#include "util.h" -- --struct seq; -- --/* Poll-block()-able barrier similar to pthread_barrier_t. */ --struct ovs_barrier_impl; --struct ovs_barrier { -- OVSRCU_TYPE(struct ovs_barrier_impl *) impl; --}; -- --/* Wrappers for pthread_mutexattr_*() that abort the process on any error. */ --void xpthread_mutexattr_init(pthread_mutexattr_t *); --void xpthread_mutexattr_destroy(pthread_mutexattr_t *); --void xpthread_mutexattr_settype(pthread_mutexattr_t *, int type); --void xpthread_mutexattr_gettype(pthread_mutexattr_t *, int *typep); -- --/* Read-write lock. -- * -- * An ovs_rwlock does not support recursive readers, because POSIX allows -- * taking the reader lock recursively to deadlock when a thread is waiting on -- * the write-lock. (NetBSD does deadlock.) glibc rwlocks in their default -- * configuration do not deadlock, but ovs_rwlock_init() initializes rwlocks as -- * non-recursive (which will deadlock) for two reasons: -- * -- * - glibc only provides fairness to writers in this mode. -- * -- * - It's better to find bugs in the primary Open vSwitch target rather -- * than exposing them only to porters. */ --struct OVS_LOCKABLE ovs_rwlock { -- pthread_rwlock_t lock; -- const char *where; /* NULL if and only if uninitialized. */ --}; -- --/* Initializer. */ --#ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP --#define OVS_RWLOCK_INITIALIZER \ -- { PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, "" } --#else --#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, "" } --#endif -- --/* ovs_rwlock functions analogous to pthread_rwlock_*() functions. -- * -- * Most of these functions abort the process with an error message on any -- * error. The "trylock" functions are exception: they pass through a 0 or -- * EBUSY return value to the caller and abort on any other error. */ --void ovs_rwlock_init(const struct ovs_rwlock *); --void ovs_rwlock_destroy(const struct ovs_rwlock *); --void ovs_rwlock_unlock(const struct ovs_rwlock *rwlock) OVS_RELEASES(rwlock); -- --/* Wrappers for pthread_rwlockattr_*() that abort the process on any error. */ --void xpthread_rwlockattr_init(pthread_rwlockattr_t *); --void xpthread_rwlockattr_destroy(pthread_rwlockattr_t *); --#ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP --void xpthread_rwlockattr_setkind_np(pthread_rwlockattr_t *, int kind); --#endif -- --void ovs_rwlock_wrlock_at(const struct ovs_rwlock *rwlock, const char *where) -- OVS_ACQ_WRLOCK(rwlock); --#define ovs_rwlock_wrlock(rwlock) \ -- ovs_rwlock_wrlock_at(rwlock, OVS_SOURCE_LOCATOR) -- --int ovs_rwlock_trywrlock_at(const struct ovs_rwlock *rwlock, const char *where) -- OVS_TRY_WRLOCK(0, rwlock); --#define ovs_rwlock_trywrlock(rwlock) \ -- ovs_rwlock_trywrlock_at(rwlock, OVS_SOURCE_LOCATOR) -- --void ovs_rwlock_rdlock_at(const struct ovs_rwlock *rwlock, const char *where) -- OVS_ACQ_RDLOCK(rwlock); --#define ovs_rwlock_rdlock(rwlock) \ -- ovs_rwlock_rdlock_at(rwlock, OVS_SOURCE_LOCATOR) -- --int ovs_rwlock_tryrdlock_at(const struct ovs_rwlock *rwlock, const char *where) -- OVS_TRY_RDLOCK(0, rwlock); --#define ovs_rwlock_tryrdlock(rwlock) \ -- ovs_rwlock_tryrdlock_at(rwlock, OVS_SOURCE_LOCATOR) -- --/* ovs_barrier functions analogous to pthread_barrier_*() functions. */ --void ovs_barrier_init(struct ovs_barrier *, uint32_t count); --void ovs_barrier_destroy(struct ovs_barrier *); --void ovs_barrier_block(struct ovs_barrier *); -- --/* Wrappers for xpthread_cond_*() that abort the process on any error. -- * -- * Use ovs_mutex_cond_wait() to wait for a condition. */ --void xpthread_cond_init(pthread_cond_t *, pthread_condattr_t *); --void xpthread_cond_destroy(pthread_cond_t *); --void xpthread_cond_signal(pthread_cond_t *); --void xpthread_cond_broadcast(pthread_cond_t *); -- --void xpthread_key_create(pthread_key_t *, void (*destructor)(void *)); --void xpthread_key_delete(pthread_key_t); --void xpthread_setspecific(pthread_key_t, const void *); -- --#ifndef _WIN32 --void xpthread_sigmask(int, const sigset_t *, sigset_t *); --#endif -- --pthread_t ovs_thread_create(const char *name, void *(*)(void *), void *); --void xpthread_join(pthread_t, void **); -- --/* Per-thread data. -- * -- * -- * Standard Forms -- * ============== -- * -- * Multiple forms of standard per-thread data exist, each with its own pluses -- * and minuses. In general, if one of these forms is appropriate, then it's a -- * good idea to use it: -- * -- * - POSIX per-thread data via pthread_key_t is portable to any pthreads -- * implementation, and allows a destructor function to be defined. It -- * only (directly) supports per-thread pointers, which are always -- * initialized to NULL. It requires once-only allocation of a -- * pthread_key_t value. It is relatively slow. Typically few -- * "pthread_key_t"s are available (POSIX requires only at least 128, -- * glibc supplies only 1024). -- * -- * - The thread_local feature newly defined in C11 works with -- * any data type and initializer, and it is fast. thread_local does not -- * require once-only initialization like pthread_key_t. C11 does not -- * define what happens if one attempts to access a thread_local object -- * from a thread other than the one to which that object belongs. There -- * is no provision to call a user-specified destructor when a thread -- * ends. Typical implementations allow for an arbitrary amount of -- * thread_local storage, but statically allocated only. -- * -- * - The __thread keyword is a GCC extension similar to thread_local but -- * with a longer history. __thread is not portable to every GCC version -- * or environment. __thread does not restrict the use of a thread-local -- * object outside its own thread. -- * -- * Here's a handy summary: -- * -- * pthread_key_t thread_local __thread -- * ------------- ------------ ------------- -- * portability high low medium -- * speed low high high -- * supports destructors? yes no no -- * needs key allocation? yes no no -- * arbitrary initializer? no yes yes -- * cross-thread access? yes no yes -- * amount available? few arbitrary arbitrary -- * dynamically allocated? yes no no -- * -- * -- * Extensions -- * ========== -- * -- * OVS provides some extensions and wrappers: -- * -- * - In a situation where the performance of thread_local or __thread is -- * desirable, but portability is required, DEFINE_STATIC_PER_THREAD_DATA -- * and DECLARE_EXTERN_PER_THREAD_DATA/DEFINE_EXTERN_PER_THREAD_DATA may -- * be appropriate (see below). -- * -- * - DEFINE_PER_THREAD_MALLOCED_DATA can be convenient for simple -- * per-thread malloc()'d buffers. -- * -- * - struct ovs_tsd provides an alternative to pthread_key_t that isn't -- * limited to a small number of keys. -- */ -- --/* For static data, use this macro in a source file: -- * -- * DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, INITIALIZER). -- * -- * For global data, "declare" the data in the header and "define" it in -- * the source file, with: -- * -- * DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME). -- * DEFINE_EXTERN_PER_THREAD_DATA(NAME, INITIALIZER). -- * -- * One should prefer to use POSIX per-thread data, via pthread_key_t, when its -- * performance is acceptable, because of its portability (see the table above). -- * This macro is an alternatives that takes advantage of thread_local (and -- * __thread), for its performance, when it is available, and falls back to -- * POSIX per-thread data otherwise. -- * -- * Defines per-thread variable NAME with the given TYPE, initialized to -- * INITIALIZER (which must be valid as an initializer for a variable with -- * static lifetime). -- * -- * The public interface to the variable is: -- * -- * TYPE *NAME_get(void) -- * TYPE *NAME_get_unsafe(void) -- * -- * Returns the address of this thread's instance of NAME. -- * -- * Use NAME_get() in a context where this might be the first use of the -- * per-thread variable in the program. Use NAME_get_unsafe(), which -- * avoids a conditional test and is thus slightly faster, in a context -- * where one knows that NAME_get() has already been called previously. -- * -- * There is no "NAME_set()" (or "NAME_set_unsafe()") function. To set the -- * value of the per-thread variable, dereference the pointer returned by -- * TYPE_get() or TYPE_get_unsafe(), e.g. *TYPE_get() = 0. -- */ --#if HAVE_THREAD_LOCAL || HAVE___THREAD -- --#if HAVE_THREAD_LOCAL --#include --#elif HAVE___THREAD --#define thread_local __thread --#else --#error --#endif -- --#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...) \ -- typedef TYPE NAME##_type; \ -- \ -- static NAME##_type * \ -- NAME##_get_unsafe(void) \ -- { \ -- static thread_local NAME##_type var = __VA_ARGS__; \ -- return &var; \ -- } \ -- \ -- static NAME##_type * \ -- NAME##_get(void) \ -- { \ -- return NAME##_get_unsafe(); \ -- } --#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME) \ -- typedef TYPE NAME##_type; \ -- extern thread_local NAME##_type NAME##_var; \ -- \ -- static inline NAME##_type * \ -- NAME##_get_unsafe(void) \ -- { \ -- return (NAME##_type *)&NAME##_var; \ -- } \ -- \ -- static inline NAME##_type * \ -- NAME##_get(void) \ -- { \ -- return NAME##_get_unsafe(); \ -- } --#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...) \ -- thread_local NAME##_type NAME##_var = __VA_ARGS__; --#else /* no C implementation support for thread-local storage */ --#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...) \ -- typedef TYPE NAME##_type; \ -- static pthread_key_t NAME##_key; \ -- \ -- static NAME##_type * \ -- NAME##_get_unsafe(void) \ -- { \ -- return pthread_getspecific(NAME##_key); \ -- } \ -- \ -- static void \ -- NAME##_once_init(void) \ -- { \ -- if (pthread_key_create(&NAME##_key, free)) { \ -- abort(); \ -- } \ -- } \ -- \ -- static NAME##_type * \ -- NAME##_get(void) \ -- { \ -- static pthread_once_t once = PTHREAD_ONCE_INIT; \ -- NAME##_type *value; \ -- \ -- pthread_once(&once, NAME##_once_init); \ -- value = NAME##_get_unsafe(); \ -- if (!value) { \ -- static const NAME##_type initial_value = __VA_ARGS__; \ -- \ -- value = xmalloc__(sizeof *value); \ -- *value = initial_value; \ -- xpthread_setspecific(NAME##_key, value); \ -- } \ -- return value; \ -- } --#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME) \ -- typedef TYPE NAME##_type; \ -- static pthread_key_t NAME##_key; \ -- \ -- static inline NAME##_type * \ -- NAME##_get_unsafe(void) \ -- { \ -- return (NAME##_type *)pthread_getspecific(NAME##_key); \ -- } \ -- \ -- NAME##_type *NAME##_get(void); --#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...) \ -- static void \ -- NAME##_once_init(void) \ -- { \ -- if (pthread_key_create(&NAME##_key, free)) { \ -- abort(); \ -- } \ -- } \ -- \ -- NAME##_type * \ -- NAME##_get(void) \ -- { \ -- static pthread_once_t once = PTHREAD_ONCE_INIT; \ -- NAME##_type *value; \ -- \ -- pthread_once(&once, NAME##_once_init); \ -- value = NAME##_get_unsafe(); \ -- if (!value) { \ -- static const NAME##_type initial_value = __VA_ARGS__; \ -- \ -- value = xmalloc__(sizeof *value); \ -- *value = initial_value; \ -- xpthread_setspecific(NAME##_key, value); \ -- } \ -- return value; \ -- } --#endif -- --/* DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME). -- * -- * This is a simple wrapper around POSIX per-thread data primitives. It -- * defines per-thread variable NAME with the given TYPE, which must be a -- * pointer type. In each thread, the per-thread variable is initialized to -- * NULL. When a thread terminates, the variable is freed with free(). -- * -- * The public interface to the variable is: -- * -- * TYPE NAME_get(void) -- * TYPE NAME_get_unsafe(void) -- * -- * Returns the value of per-thread variable NAME in this thread. -- * -- * Use NAME_get() in a context where this might be the first use of the -- * per-thread variable in the program. Use NAME_get_unsafe(), which -- * avoids a conditional test and is thus slightly faster, in a context -- * where one knows that NAME_get() has already been called previously. -- * -- * TYPE NAME_set(TYPE new_value) -- * TYPE NAME_set_unsafe(TYPE new_value) -- * -- * Sets the value of per-thread variable NAME to 'new_value' in this -- * thread, and returns its previous value. -- * -- * Use NAME_set() in a context where this might be the first use of the -- * per-thread variable in the program. Use NAME_set_unsafe(), which -- * avoids a conditional test and is thus slightly faster, in a context -- * where one knows that NAME_set() has already been called previously. -- */ --#define DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME) \ -- static pthread_key_t NAME##_key; \ -- \ -- static void \ -- NAME##_once_init(void) \ -- { \ -- if (pthread_key_create(&NAME##_key, free)) { \ -- abort(); \ -- } \ -- } \ -- \ -- static void \ -- NAME##_init(void) \ -- { \ -- static pthread_once_t once = PTHREAD_ONCE_INIT; \ -- pthread_once(&once, NAME##_once_init); \ -- } \ -- \ -- static TYPE \ -- NAME##_get_unsafe(void) \ -- { \ -- return pthread_getspecific(NAME##_key); \ -- } \ -- \ -- static OVS_UNUSED TYPE \ -- NAME##_get(void) \ -- { \ -- NAME##_init(); \ -- return NAME##_get_unsafe(); \ -- } \ -- \ -- static TYPE \ -- NAME##_set_unsafe(TYPE value) \ -- { \ -- TYPE old_value = NAME##_get_unsafe(); \ -- xpthread_setspecific(NAME##_key, value); \ -- return old_value; \ -- } \ -- \ -- static OVS_UNUSED TYPE \ -- NAME##_set(TYPE value) \ -- { \ -- NAME##_init(); \ -- return NAME##_set_unsafe(value); \ -- } -- --/* Dynamically allocated thread-specific data with lots of slots. -- * -- * pthread_key_t can provide as few as 128 pieces of thread-specific data (even -- * glibc is limited to 1,024). Thus, one must be careful to allocate only a -- * few keys globally. One cannot, for example, allocate a key for every -- * instance of a data structure if there might be an arbitrary number of those -- * data structures. -- * -- * This API is similar to the pthread one (simply search and replace pthread_ -- * by ovsthread_) but it a much larger limit that can be raised if necessary -- * (by recompiling). Thus, one may more freely use this form of -- * thread-specific data. -- * -- * ovsthread_key_t also differs from pthread_key_t in the following ways: -- * -- * - Destructors must not access thread-specific data (via ovsthread_key). -- * -- * - The pthread_key_t API allows concurrently exiting threads to start -- * executing the destructor after pthread_key_delete() returns. The -- * ovsthread_key_t API guarantees that, when ovsthread_key_delete() -- * returns, all destructors have returned and no new ones will start -- * execution. -- */ --typedef struct ovsthread_key *ovsthread_key_t; -- --void ovsthread_key_create(ovsthread_key_t *, void (*destructor)(void *)); --void ovsthread_key_delete(ovsthread_key_t); -- --void ovsthread_setspecific(ovsthread_key_t, const void *); --void *ovsthread_getspecific(ovsthread_key_t); -- --/* Thread ID. -- * -- * pthread_t isn't so nice for some purposes. Its size and representation are -- * implementation dependent, which means that there is no way to hash it. -- * This thread ID avoids the problem. -- */ -- --#define OVSTHREAD_ID_UNSET UINT_MAX --DECLARE_EXTERN_PER_THREAD_DATA(unsigned int, ovsthread_id); -- --/* Initializes the unique per thread identifier */ --unsigned int ovsthread_id_init(void); -- --/* Returns a per-thread identifier unique within the lifetime of the -- * process. */ --static inline unsigned int --ovsthread_id_self(void) --{ -- unsigned int id = *ovsthread_id_get(); -- -- if (OVS_UNLIKELY(id == OVSTHREAD_ID_UNSET)) { -- id = ovsthread_id_init(); -- } -- -- return id; --} -- --/* Simulated global counter. -- * -- * Incrementing such a counter is meant to be cheaper than incrementing a -- * global counter protected by a lock. It is probably more expensive than -- * incrementing a truly thread-local variable, but such a variable has no -- * straightforward way to get the sum. -- * -- * -- * Thread-safety -- * ============= -- * -- * Fully thread-safe. */ -- --struct ovsthread_stats { -- struct ovs_mutex mutex; -- void *volatile buckets[16]; --}; -- --void ovsthread_stats_init(struct ovsthread_stats *); --void ovsthread_stats_destroy(struct ovsthread_stats *); -- --void *ovsthread_stats_bucket_get(struct ovsthread_stats *, -- void *(*new_bucket)(void)); -- --#define OVSTHREAD_STATS_FOR_EACH_BUCKET(BUCKET, IDX, STATS) \ -- for ((IDX) = ovs_thread_stats_next_bucket(STATS, 0); \ -- ((IDX) < ARRAY_SIZE((STATS)->buckets) \ -- ? ((BUCKET) = (STATS)->buckets[IDX], true) \ -- : false); \ -- (IDX) = ovs_thread_stats_next_bucket(STATS, (IDX) + 1)) --size_t ovs_thread_stats_next_bucket(const struct ovsthread_stats *, size_t); -- --bool single_threaded(void); -- --void assert_single_threaded_at(const char *where); --#define assert_single_threaded() assert_single_threaded_at(OVS_SOURCE_LOCATOR) -- --#ifndef _WIN32 --pid_t xfork_at(const char *where); --#define xfork() xfork_at(OVS_SOURCE_LOCATOR) --#endif -- --void forbid_forking(const char *reason); --bool may_fork(void); -- --/* Useful functions related to threading. */ -- --int count_cpu_cores(void); --bool thread_is_pmd(void); -- --#endif /* ovs-thread.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovs-thread.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovs-thread.h -@@ -0,0 +1,535 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVS_THREAD_H -+#define OVS_THREAD_H 1 -+ -+#include -+#include -+#include -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/thread.h" -+#include "internal/util.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct seq; -+ -+/* Poll-block()-able barrier similar to pthread_barrier_t. */ -+struct ovs_barrier_impl; -+struct ovs_barrier { -+ OVSRCU_TYPE(struct ovs_barrier_impl *) impl; -+}; -+ -+/* Wrappers for pthread_mutexattr_*() that abort the process on any error. */ -+void xpthread_mutexattr_init(pthread_mutexattr_t *); -+void xpthread_mutexattr_destroy(pthread_mutexattr_t *); -+void xpthread_mutexattr_settype(pthread_mutexattr_t *, int type); -+void xpthread_mutexattr_gettype(pthread_mutexattr_t *, int *typep); -+ -+/* Read-write lock. -+ * -+ * An ovs_rwlock does not support recursive readers, because POSIX allows -+ * taking the reader lock recursively to deadlock when a thread is waiting on -+ * the write-lock. (NetBSD does deadlock.) glibc rwlocks in their default -+ * configuration do not deadlock, but ovs_rwlock_init() initializes rwlocks as -+ * non-recursive (which will deadlock) for two reasons: -+ * -+ * - glibc only provides fairness to writers in this mode. -+ * -+ * - It's better to find bugs in the primary Open vSwitch target rather -+ * than exposing them only to porters. */ -+struct OVS_LOCKABLE ovs_rwlock { -+ pthread_rwlock_t lock; -+ const char *where; /* NULL if and only if uninitialized. */ -+}; -+ -+/* Initializer. */ -+#ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP -+#define OVS_RWLOCK_INITIALIZER \ -+ { PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, "" } -+#else -+#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, "" } -+#endif -+ -+/* ovs_rwlock functions analogous to pthread_rwlock_*() functions. -+ * -+ * Most of these functions abort the process with an error message on any -+ * error. The "trylock" functions are exception: they pass through a 0 or -+ * EBUSY return value to the caller and abort on any other error. */ -+void ovs_rwlock_init(const struct ovs_rwlock *); -+void ovs_rwlock_destroy(const struct ovs_rwlock *); -+void ovs_rwlock_unlock(const struct ovs_rwlock *rwlock) OVS_RELEASES(rwlock); -+ -+/* Wrappers for pthread_rwlockattr_*() that abort the process on any error. */ -+void xpthread_rwlockattr_init(pthread_rwlockattr_t *); -+void xpthread_rwlockattr_destroy(pthread_rwlockattr_t *); -+#ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP -+void xpthread_rwlockattr_setkind_np(pthread_rwlockattr_t *, int kind); -+#endif -+ -+void ovs_rwlock_wrlock_at(const struct ovs_rwlock *rwlock, const char *where) -+ OVS_ACQ_WRLOCK(rwlock); -+#define ovs_rwlock_wrlock(rwlock) \ -+ ovs_rwlock_wrlock_at(rwlock, OVS_SOURCE_LOCATOR) -+ -+int ovs_rwlock_trywrlock_at(const struct ovs_rwlock *rwlock, const char *where) -+ OVS_TRY_WRLOCK(0, rwlock); -+#define ovs_rwlock_trywrlock(rwlock) \ -+ ovs_rwlock_trywrlock_at(rwlock, OVS_SOURCE_LOCATOR) -+ -+void ovs_rwlock_rdlock_at(const struct ovs_rwlock *rwlock, const char *where) -+ OVS_ACQ_RDLOCK(rwlock); -+#define ovs_rwlock_rdlock(rwlock) \ -+ ovs_rwlock_rdlock_at(rwlock, OVS_SOURCE_LOCATOR) -+ -+int ovs_rwlock_tryrdlock_at(const struct ovs_rwlock *rwlock, const char *where) -+ OVS_TRY_RDLOCK(0, rwlock); -+#define ovs_rwlock_tryrdlock(rwlock) \ -+ ovs_rwlock_tryrdlock_at(rwlock, OVS_SOURCE_LOCATOR) -+ -+/* ovs_barrier functions analogous to pthread_barrier_*() functions. */ -+void ovs_barrier_init(struct ovs_barrier *, uint32_t count); -+void ovs_barrier_destroy(struct ovs_barrier *); -+void ovs_barrier_block(struct ovs_barrier *); -+ -+/* Wrappers for xpthread_cond_*() that abort the process on any error. -+ * -+ * Use ovs_mutex_cond_wait() to wait for a condition. */ -+void xpthread_cond_init(pthread_cond_t *, pthread_condattr_t *); -+void xpthread_cond_destroy(pthread_cond_t *); -+void xpthread_cond_signal(pthread_cond_t *); -+void xpthread_cond_broadcast(pthread_cond_t *); -+ -+void xpthread_key_create(pthread_key_t *, void (*destructor)(void *)); -+void xpthread_key_delete(pthread_key_t); -+void xpthread_setspecific(pthread_key_t, const void *); -+ -+#ifndef _WIN32 -+void xpthread_sigmask(int, const sigset_t *, sigset_t *); -+#endif -+ -+pthread_t ovs_thread_create(const char *name, void *(*)(void *), void *); -+void xpthread_join(pthread_t, void **); -+ -+/* Per-thread data. -+ * -+ * -+ * Standard Forms -+ * ============== -+ * -+ * Multiple forms of standard per-thread data exist, each with its own pluses -+ * and minuses. In general, if one of these forms is appropriate, then it's a -+ * good idea to use it: -+ * -+ * - POSIX per-thread data via pthread_key_t is portable to any pthreads -+ * implementation, and allows a destructor function to be defined. It -+ * only (directly) supports per-thread pointers, which are always -+ * initialized to NULL. It requires once-only allocation of a -+ * pthread_key_t value. It is relatively slow. Typically few -+ * "pthread_key_t"s are available (POSIX requires only at least 128, -+ * glibc supplies only 1024). -+ * -+ * - The thread_local feature newly defined in C11 works with -+ * any data type and initializer, and it is fast. thread_local does not -+ * require once-only initialization like pthread_key_t. C11 does not -+ * define what happens if one attempts to access a thread_local object -+ * from a thread other than the one to which that object belongs. There -+ * is no provision to call a user-specified destructor when a thread -+ * ends. Typical implementations allow for an arbitrary amount of -+ * thread_local storage, but statically allocated only. -+ * -+ * - The __thread keyword is a GCC extension similar to thread_local but -+ * with a longer history. __thread is not portable to every GCC version -+ * or environment. __thread does not restrict the use of a thread-local -+ * object outside its own thread. -+ * -+ * Here's a handy summary: -+ * -+ * pthread_key_t thread_local __thread -+ * ------------- ------------ ------------- -+ * portability high low medium -+ * speed low high high -+ * supports destructors? yes no no -+ * needs key allocation? yes no no -+ * arbitrary initializer? no yes yes -+ * cross-thread access? yes no yes -+ * amount available? few arbitrary arbitrary -+ * dynamically allocated? yes no no -+ * -+ * -+ * Extensions -+ * ========== -+ * -+ * OVS provides some extensions and wrappers: -+ * -+ * - In a situation where the performance of thread_local or __thread is -+ * desirable, but portability is required, DEFINE_STATIC_PER_THREAD_DATA -+ * and DECLARE_EXTERN_PER_THREAD_DATA/DEFINE_EXTERN_PER_THREAD_DATA may -+ * be appropriate (see below). -+ * -+ * - DEFINE_PER_THREAD_MALLOCED_DATA can be convenient for simple -+ * per-thread malloc()'d buffers. -+ * -+ * - struct ovs_tsd provides an alternative to pthread_key_t that isn't -+ * limited to a small number of keys. -+ */ -+ -+/* For static data, use this macro in a source file: -+ * -+ * DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, INITIALIZER). -+ * -+ * For global data, "declare" the data in the header and "define" it in -+ * the source file, with: -+ * -+ * DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME). -+ * DEFINE_EXTERN_PER_THREAD_DATA(NAME, INITIALIZER). -+ * -+ * One should prefer to use POSIX per-thread data, via pthread_key_t, when its -+ * performance is acceptable, because of its portability (see the table above). -+ * This macro is an alternatives that takes advantage of thread_local (and -+ * __thread), for its performance, when it is available, and falls back to -+ * POSIX per-thread data otherwise. -+ * -+ * Defines per-thread variable NAME with the given TYPE, initialized to -+ * INITIALIZER (which must be valid as an initializer for a variable with -+ * static lifetime). -+ * -+ * The public interface to the variable is: -+ * -+ * TYPE *NAME_get(void) -+ * TYPE *NAME_get_unsafe(void) -+ * -+ * Returns the address of this thread's instance of NAME. -+ * -+ * Use NAME_get() in a context where this might be the first use of the -+ * per-thread variable in the program. Use NAME_get_unsafe(), which -+ * avoids a conditional test and is thus slightly faster, in a context -+ * where one knows that NAME_get() has already been called previously. -+ * -+ * There is no "NAME_set()" (or "NAME_set_unsafe()") function. To set the -+ * value of the per-thread variable, dereference the pointer returned by -+ * TYPE_get() or TYPE_get_unsafe(), e.g. *TYPE_get() = 0. -+ */ -+#if HAVE_THREAD_LOCAL || HAVE___THREAD -+ -+#if HAVE_THREAD_LOCAL -+#include -+#elif HAVE___THREAD -+#define thread_local __thread -+#else -+#error -+#endif -+ -+#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...) \ -+ typedef TYPE NAME##_type; \ -+ \ -+ static NAME##_type * \ -+ NAME##_get_unsafe(void) \ -+ { \ -+ static thread_local NAME##_type var = __VA_ARGS__; \ -+ return &var; \ -+ } \ -+ \ -+ static NAME##_type * \ -+ NAME##_get(void) \ -+ { \ -+ return NAME##_get_unsafe(); \ -+ } -+#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME) \ -+ typedef TYPE NAME##_type; \ -+ extern thread_local NAME##_type NAME##_var; \ -+ \ -+ static inline NAME##_type * \ -+ NAME##_get_unsafe(void) \ -+ { \ -+ return (NAME##_type *)&NAME##_var; \ -+ } \ -+ \ -+ static inline NAME##_type * \ -+ NAME##_get(void) \ -+ { \ -+ return NAME##_get_unsafe(); \ -+ } -+#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...) \ -+ thread_local NAME##_type NAME##_var = __VA_ARGS__; -+#else /* no C implementation support for thread-local storage */ -+#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...) \ -+ typedef TYPE NAME##_type; \ -+ static pthread_key_t NAME##_key; \ -+ \ -+ static NAME##_type * \ -+ NAME##_get_unsafe(void) \ -+ { \ -+ return pthread_getspecific(NAME##_key); \ -+ } \ -+ \ -+ static void \ -+ NAME##_once_init(void) \ -+ { \ -+ if (pthread_key_create(&NAME##_key, free)) { \ -+ abort(); \ -+ } \ -+ } \ -+ \ -+ static NAME##_type * \ -+ NAME##_get(void) \ -+ { \ -+ static pthread_once_t once = PTHREAD_ONCE_INIT; \ -+ NAME##_type *value; \ -+ \ -+ pthread_once(&once, NAME##_once_init); \ -+ value = NAME##_get_unsafe(); \ -+ if (!value) { \ -+ static const NAME##_type initial_value = __VA_ARGS__; \ -+ \ -+ value = xmalloc__(sizeof *value); \ -+ *value = initial_value; \ -+ xpthread_setspecific(NAME##_key, value); \ -+ } \ -+ return value; \ -+ } -+#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME) \ -+ typedef TYPE NAME##_type; \ -+ static pthread_key_t NAME##_key; \ -+ \ -+ static inline NAME##_type * \ -+ NAME##_get_unsafe(void) \ -+ { \ -+ return (NAME##_type *)pthread_getspecific(NAME##_key); \ -+ } \ -+ \ -+ NAME##_type *NAME##_get(void); -+#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...) \ -+ static void \ -+ NAME##_once_init(void) \ -+ { \ -+ if (pthread_key_create(&NAME##_key, free)) { \ -+ abort(); \ -+ } \ -+ } \ -+ \ -+ NAME##_type * \ -+ NAME##_get(void) \ -+ { \ -+ static pthread_once_t once = PTHREAD_ONCE_INIT; \ -+ NAME##_type *value; \ -+ \ -+ pthread_once(&once, NAME##_once_init); \ -+ value = NAME##_get_unsafe(); \ -+ if (!value) { \ -+ static const NAME##_type initial_value = __VA_ARGS__; \ -+ \ -+ value = xmalloc__(sizeof *value); \ -+ *value = initial_value; \ -+ xpthread_setspecific(NAME##_key, value); \ -+ } \ -+ return value; \ -+ } -+#endif -+ -+/* DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME). -+ * -+ * This is a simple wrapper around POSIX per-thread data primitives. It -+ * defines per-thread variable NAME with the given TYPE, which must be a -+ * pointer type. In each thread, the per-thread variable is initialized to -+ * NULL. When a thread terminates, the variable is freed with free(). -+ * -+ * The public interface to the variable is: -+ * -+ * TYPE NAME_get(void) -+ * TYPE NAME_get_unsafe(void) -+ * -+ * Returns the value of per-thread variable NAME in this thread. -+ * -+ * Use NAME_get() in a context where this might be the first use of the -+ * per-thread variable in the program. Use NAME_get_unsafe(), which -+ * avoids a conditional test and is thus slightly faster, in a context -+ * where one knows that NAME_get() has already been called previously. -+ * -+ * TYPE NAME_set(TYPE new_value) -+ * TYPE NAME_set_unsafe(TYPE new_value) -+ * -+ * Sets the value of per-thread variable NAME to 'new_value' in this -+ * thread, and returns its previous value. -+ * -+ * Use NAME_set() in a context where this might be the first use of the -+ * per-thread variable in the program. Use NAME_set_unsafe(), which -+ * avoids a conditional test and is thus slightly faster, in a context -+ * where one knows that NAME_set() has already been called previously. -+ */ -+#define DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME) \ -+ static pthread_key_t NAME##_key; \ -+ \ -+ static void \ -+ NAME##_once_init(void) \ -+ { \ -+ if (pthread_key_create(&NAME##_key, free)) { \ -+ abort(); \ -+ } \ -+ } \ -+ \ -+ static void \ -+ NAME##_init(void) \ -+ { \ -+ static pthread_once_t once = PTHREAD_ONCE_INIT; \ -+ pthread_once(&once, NAME##_once_init); \ -+ } \ -+ \ -+ static TYPE \ -+ NAME##_get_unsafe(void) \ -+ { \ -+ return pthread_getspecific(NAME##_key); \ -+ } \ -+ \ -+ static OVS_UNUSED TYPE \ -+ NAME##_get(void) \ -+ { \ -+ NAME##_init(); \ -+ return NAME##_get_unsafe(); \ -+ } \ -+ \ -+ static TYPE \ -+ NAME##_set_unsafe(TYPE value) \ -+ { \ -+ TYPE old_value = NAME##_get_unsafe(); \ -+ xpthread_setspecific(NAME##_key, value); \ -+ return old_value; \ -+ } \ -+ \ -+ static OVS_UNUSED TYPE \ -+ NAME##_set(TYPE value) \ -+ { \ -+ NAME##_init(); \ -+ return NAME##_set_unsafe(value); \ -+ } -+ -+/* Dynamically allocated thread-specific data with lots of slots. -+ * -+ * pthread_key_t can provide as few as 128 pieces of thread-specific data (even -+ * glibc is limited to 1,024). Thus, one must be careful to allocate only a -+ * few keys globally. One cannot, for example, allocate a key for every -+ * instance of a data structure if there might be an arbitrary number of those -+ * data structures. -+ * -+ * This API is similar to the pthread one (simply search and replace pthread_ -+ * by ovsthread_) but it a much larger limit that can be raised if necessary -+ * (by recompiling). Thus, one may more freely use this form of -+ * thread-specific data. -+ * -+ * ovsthread_key_t also differs from pthread_key_t in the following ways: -+ * -+ * - Destructors must not access thread-specific data (via ovsthread_key). -+ * -+ * - The pthread_key_t API allows concurrently exiting threads to start -+ * executing the destructor after pthread_key_delete() returns. The -+ * ovsthread_key_t API guarantees that, when ovsthread_key_delete() -+ * returns, all destructors have returned and no new ones will start -+ * execution. -+ */ -+typedef struct ovsthread_key *ovsthread_key_t; -+ -+void ovsthread_key_create(ovsthread_key_t *, void (*destructor)(void *)); -+void ovsthread_key_delete(ovsthread_key_t); -+ -+void ovsthread_setspecific(ovsthread_key_t, const void *); -+void *ovsthread_getspecific(ovsthread_key_t); -+ -+/* Thread ID. -+ * -+ * pthread_t isn't so nice for some purposes. Its size and representation are -+ * implementation dependent, which means that there is no way to hash it. -+ * This thread ID avoids the problem. -+ */ -+ -+#define OVSTHREAD_ID_UNSET UINT_MAX -+DECLARE_EXTERN_PER_THREAD_DATA(unsigned int, ovsthread_id); -+ -+/* Initializes the unique per thread identifier */ -+unsigned int ovsthread_id_init(void); -+ -+/* Returns a per-thread identifier unique within the lifetime of the -+ * process. */ -+static inline unsigned int -+ovsthread_id_self(void) -+{ -+ unsigned int id = *ovsthread_id_get(); -+ -+ if (OVS_UNLIKELY(id == OVSTHREAD_ID_UNSET)) { -+ id = ovsthread_id_init(); -+ } -+ -+ return id; -+} -+ -+/* Simulated global counter. -+ * -+ * Incrementing such a counter is meant to be cheaper than incrementing a -+ * global counter protected by a lock. It is probably more expensive than -+ * incrementing a truly thread-local variable, but such a variable has no -+ * straightforward way to get the sum. -+ * -+ * -+ * Thread-safety -+ * ============= -+ * -+ * Fully thread-safe. */ -+ -+struct ovsthread_stats { -+ struct ovs_mutex mutex; -+ void *volatile buckets[16]; -+}; -+ -+void ovsthread_stats_init(struct ovsthread_stats *); -+void ovsthread_stats_destroy(struct ovsthread_stats *); -+ -+void *ovsthread_stats_bucket_get(struct ovsthread_stats *, -+ void *(*new_bucket)(void)); -+ -+#define OVSTHREAD_STATS_FOR_EACH_BUCKET(BUCKET, IDX, STATS) \ -+ for ((IDX) = ovs_thread_stats_next_bucket(STATS, 0); \ -+ ((IDX) < ARRAY_SIZE((STATS)->buckets) \ -+ ? ((BUCKET) = (STATS)->buckets[IDX], true) \ -+ : false); \ -+ (IDX) = ovs_thread_stats_next_bucket(STATS, (IDX) + 1)) -+size_t ovs_thread_stats_next_bucket(const struct ovsthread_stats *, size_t); -+ -+bool single_threaded(void); -+ -+void assert_single_threaded_at(const char *where); -+#define assert_single_threaded() assert_single_threaded_at(OVS_SOURCE_LOCATOR) -+ -+#ifndef _WIN32 -+pid_t xfork_at(const char *where); -+#define xfork() xfork_at(OVS_SOURCE_LOCATOR) -+#endif -+ -+void forbid_forking(const char *reason); -+bool may_fork(void); -+ -+/* Useful functions related to threading. */ -+ -+int count_cpu_cores(void); -+bool thread_is_pmd(void); -+ -+#ifdef __cplusplus -+} // extern "C" -+#endif -+ -+#endif /* ovs-thread.h */ -Index: openvswitch-2.17.2/lib/ovsdb-condition.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-condition.h -+++ /dev/null -@@ -1,45 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_LIB_CONDITION_H --#define OVSDB_LIB_CONDITION_H 1 -- --/* These list is ordered first with boolean functions and then in -- * ascending order of the fraction of tables row that they are -- * (heuristically) expected to leave in query results. */ --#define OVSDB_FUNCTIONS \ -- OVSDB_FUNCTION(OVSDB_F_FALSE, "false") \ -- OVSDB_FUNCTION(OVSDB_F_TRUE, "true") \ -- OVSDB_FUNCTION(OVSDB_F_EQ, "==") \ -- OVSDB_FUNCTION(OVSDB_F_INCLUDES, "includes") \ -- OVSDB_FUNCTION(OVSDB_F_LE, "<=") \ -- OVSDB_FUNCTION(OVSDB_F_LT, "<") \ -- OVSDB_FUNCTION(OVSDB_F_GE, ">=") \ -- OVSDB_FUNCTION(OVSDB_F_GT, ">") \ -- OVSDB_FUNCTION(OVSDB_F_EXCLUDES, "excludes") \ -- OVSDB_FUNCTION(OVSDB_F_NE, "!=") -- --enum ovsdb_function { --#define OVSDB_FUNCTION(ENUM, NAME) ENUM, -- OVSDB_FUNCTIONS --#undef OVSDB_FUNCTION -- OVSDB_F_LAST = OVSDB_F_NE --}; -- --struct ovsdb_error * ovsdb_function_from_string(const char *name, -- enum ovsdb_function *function); --const char * ovsdb_function_to_string(enum ovsdb_function function); -- --#endif /* ovsdb-condition.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-condition.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-condition.h -@@ -0,0 +1,53 @@ -+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_LIB_CONDITION_H -+#define OVSDB_LIB_CONDITION_H 1 -+ -+/* These list is ordered first with boolean functions and then in -+ * ascending order of the fraction of tables row that they are -+ * (heuristically) expected to leave in query results. */ -+#define OVSDB_FUNCTIONS \ -+ OVSDB_FUNCTION(OVSDB_F_FALSE, "false") \ -+ OVSDB_FUNCTION(OVSDB_F_TRUE, "true") \ -+ OVSDB_FUNCTION(OVSDB_F_EQ, "==") \ -+ OVSDB_FUNCTION(OVSDB_F_INCLUDES, "includes") \ -+ OVSDB_FUNCTION(OVSDB_F_LE, "<=") \ -+ OVSDB_FUNCTION(OVSDB_F_LT, "<") \ -+ OVSDB_FUNCTION(OVSDB_F_GE, ">=") \ -+ OVSDB_FUNCTION(OVSDB_F_GT, ">") \ -+ OVSDB_FUNCTION(OVSDB_F_EXCLUDES, "excludes") \ -+ OVSDB_FUNCTION(OVSDB_F_NE, "!=") -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+enum ovsdb_function { -+#define OVSDB_FUNCTION(ENUM, NAME) ENUM, -+ OVSDB_FUNCTIONS -+#undef OVSDB_FUNCTION -+ OVSDB_F_LAST = OVSDB_F_NE -+}; -+ -+struct ovsdb_error * ovsdb_function_from_string(const char *name, -+ enum ovsdb_function *function); -+const char * ovsdb_function_to_string(enum ovsdb_function function); -+ -+#ifdef __cplusplus -+} // extern "C" { -+#endif -+ -+#endif /* ovsdb-condition.h */ -Index: openvswitch-2.17.2/lib/ovsdb-cs.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-cs.h -+++ /dev/null -@@ -1,205 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. -- * Copyright (C) 2016 Hewlett Packard Enterprise Development LP -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_CS_H --#define OVSDB_CS_H 1 -- --/* Open vSwitch Database client synchronization layer. -- * -- * This is a base layer for maintaining an in-memory replica of a database. It -- * issues RPC requests to an OVSDB database server and passes the semantically -- * meaningful parts of the stream up to a higher layer. The OVSDB IDL uses -- * this as a base layer, as well as OVN's DDlog-based northd implementation. -- */ -- --#include --#include "openvswitch/hmap.h" --#include "openvswitch/list.h" --#include "openvswitch/shash.h" --#include "openvswitch/uuid.h" -- --struct json; --struct ovsdb_cs; -- --struct ovsdb_cs_ops { -- /* Returns to use for the specified . The -- * implementation might find ovsdb_cs_parse_table_updates() to be a useful -- * helper. -- * -- * The caller might actually use "monitor_cond" or "monitor_cond_since", -- * rather than plain "monitor". If so, this function's implementation -- * doesn't need to worry about that, because the caller will add the -- * conditions itself. */ -- struct json *(*compose_monitor_requests)(const struct json *schema, -- void *aux); --}; -- --/* An event is a happening that is worth reporting to the CS client. -- * -- * Currently there are three kinds of events: -- * -- * - "Reconnect": The connection to the database was lost and it is now -- * being reconnected. This means that any transactions submitted by the -- * client will never receive a reply (although it's possible that some of -- * them were actually committed). This event has no associated data. -- * -- * - "Locked": The server granted the lock we requested. -- * -- * - "Update": The server sent an update to one or more monitored tables. -- * The client can use the associated data to update its idea of the -- * snapshot. -- * -- * - "Transaction reply": The server sent a reply to a transaction sent by -- * the client using ovsdb_cs_send_transaction(). -- */ --struct ovsdb_cs_event { -- struct ovs_list list_node; -- -- enum ovsdb_cs_event_type { -- OVSDB_CS_EVENT_TYPE_RECONNECT, /* Connection lost. */ -- OVSDB_CS_EVENT_TYPE_LOCKED, /* Got the lock we wanted. */ -- OVSDB_CS_EVENT_TYPE_UPDATE, /* Received update notification. */ -- OVSDB_CS_EVENT_TYPE_TXN_REPLY, /* Received reply to transaction. */ -- } type; -- -- union { -- /* Represents a or that contains -- * either the initial data in a monitor reply or a delta received in an -- * update notification. The client can use this to update its database -- * replica. -- * -- * If 'clear' is true, then the client should first clear its idea of -- * what's in the replica before applying the update; otherwise, it's an -- * incremental update. -- * -- * If 'monitor_reply' is true, then this comes from a monitor reply. -- * This doesn't have real semantic meaning, but it allows the caller -- * to imitate the exact behavior of previous versions of code that -- * behaved differently on updates from monitor replies vs. updates. -- * -- * 'table-updates' is a if 'version' if 1, otherwise a -- * . The client can use ovsdb_cs_parse_table_updates() -- * to parse the update. -- */ -- struct ovsdb_cs_update_event { -- bool clear; -- bool monitor_reply; -- struct json *table_updates; -- int version; -- } update; -- -- /* The "result" member from a transaction reply. The transaction is -- * one sent by the client using ovsdb_cs_send_transaction(). The -- * client can match 'txn_reply->id' against the ID in a transaction it -- * sent. */ -- struct jsonrpc_msg *txn_reply; -- }; --}; --void ovsdb_cs_event_destroy(struct ovsdb_cs_event *); -- --/* Lifecycle. */ --struct ovsdb_cs *ovsdb_cs_create(const char *database, int max_version, -- const struct ovsdb_cs_ops *ops, -- void *ops_aux); --void ovsdb_cs_destroy(struct ovsdb_cs *); -- --void ovsdb_cs_run(struct ovsdb_cs *, struct ovs_list *events); --void ovsdb_cs_wait(struct ovsdb_cs *); -- --/* Network connection. */ --void ovsdb_cs_set_remote(struct ovsdb_cs *, const char *remote, bool retry); -- --void ovsdb_cs_enable_reconnect(struct ovsdb_cs *); --void ovsdb_cs_force_reconnect(struct ovsdb_cs *); --void ovsdb_cs_flag_inconsistency(struct ovsdb_cs *); -- --bool ovsdb_cs_is_alive(const struct ovsdb_cs *); --bool ovsdb_cs_is_connected(const struct ovsdb_cs *); --int ovsdb_cs_get_last_error(const struct ovsdb_cs *); -- --void ovsdb_cs_set_probe_interval(const struct ovsdb_cs *, int probe_interval); -- --/* Conditional monitoring (specifying that only rows matching particular -- * criteria should be monitored). -- * -- * Some database servers don't support conditional monitoring; in that case, -- * the client will get all the rows. */ --unsigned int ovsdb_cs_set_condition(struct ovsdb_cs *, const char *table, -- const struct json *condition); --unsigned int ovsdb_cs_get_condition_seqno(const struct ovsdb_cs *); -- --/* Clustered servers. */ --void ovsdb_cs_set_leader_only(struct ovsdb_cs *, bool leader_only); --void ovsdb_cs_set_shuffle_remotes(struct ovsdb_cs *, bool shuffle); --void ovsdb_cs_reset_min_index(struct ovsdb_cs *); -- --/* Database locks. */ --void ovsdb_cs_set_lock(struct ovsdb_cs *, const char *lock_name); --const char *ovsdb_cs_get_lock(const struct ovsdb_cs *); --bool ovsdb_cs_has_lock(const struct ovsdb_cs *); --bool ovsdb_cs_is_lock_contended(const struct ovsdb_cs *); -- --/* Transactions. */ --bool ovsdb_cs_may_send_transaction(const struct ovsdb_cs *); --struct json *ovsdb_cs_send_transaction(struct ovsdb_cs *, struct json *ops) -- OVS_WARN_UNUSED_RESULT; --bool ovsdb_cs_forget_transaction(struct ovsdb_cs *, const struct json *); -- --/* Helper for partially parsing the or that -- * appear in struct ovsdb_cs_update_event. The helper leaves the data in JSON -- * format, so it doesn't need to know column types. */ -- --/* The kind of change to a row. */ --enum ovsdb_cs_row_update_type { -- OVSDB_CS_ROW_DELETE, /* Row deletion. */ -- OVSDB_CS_ROW_INSERT, /* Row insertion. */ -- OVSDB_CS_ROW_UPDATE, /* Replacement of data within a row. */ -- OVSDB_CS_ROW_XOR /* diff application. */ --}; -- --/* Partially parsed or . */ --struct ovsdb_cs_row_update { -- struct uuid row_uuid; /* Row's _uuid. */ -- enum ovsdb_cs_row_update_type type; /* Type of change. */ -- const struct shash *columns; /* Map from column name to json data. */ --}; -- --/* Partially parsed or . */ --struct ovsdb_cs_table_update { -- const char *table_name; -- struct ovsdb_cs_row_update *row_updates; -- size_t n; --}; -- --struct ovsdb_cs_db_update { -- struct ovsdb_cs_table_update *table_updates; -- size_t n; --}; -- --struct ovsdb_error *ovsdb_cs_parse_db_update( -- const struct json *table_updates, int version, -- struct ovsdb_cs_db_update **db_updatep) -- OVS_WARN_UNUSED_RESULT; --void ovsdb_cs_db_update_destroy(struct ovsdb_cs_db_update *); --const struct ovsdb_cs_table_update *ovsdb_cs_db_update_find_table( -- const struct ovsdb_cs_db_update *, const char *table_name); -- --/* Simple parsing of OVSDB schemas for use by ovsdb_cs clients. */ -- --struct shash *ovsdb_cs_parse_schema(const struct json *schema_json); --void ovsdb_cs_free_schema(struct shash *schema); -- --#endif /* ovsdb-cs.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-cs.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-cs.h -@@ -0,0 +1,213 @@ -+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc. -+ * Copyright (C) 2016 Hewlett Packard Enterprise Development LP -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_CS_H -+#define OVSDB_CS_H 1 -+ -+/* Open vSwitch Database client synchronization layer. -+ * -+ * This is a base layer for maintaining an in-memory replica of a database. It -+ * issues RPC requests to an OVSDB database server and passes the semantically -+ * meaningful parts of the stream up to a higher layer. The OVSDB IDL uses -+ * this as a base layer, as well as OVN's DDlog-based northd implementation. -+ */ -+ -+#include -+#include "openvswitch/hmap.h" -+#include "openvswitch/list.h" -+#include "openvswitch/shash.h" -+#include "openvswitch/uuid.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct json; -+struct ovsdb_cs; -+ -+struct ovsdb_cs_ops { -+ /* Returns to use for the specified . The -+ * implementation might find ovsdb_cs_parse_table_updates() to be a useful -+ * helper. -+ * -+ * The caller might actually use "monitor_cond" or "monitor_cond_since", -+ * rather than plain "monitor". If so, this function's implementation -+ * doesn't need to worry about that, because the caller will add the -+ * conditions itself. */ -+ struct json *(*compose_monitor_requests)(const struct json *schema, -+ void *aux); -+}; -+ -+/* An event is a happening that is worth reporting to the CS client. -+ * -+ * Currently there are three kinds of events: -+ * -+ * - "Reconnect": The connection to the database was lost and it is now -+ * being reconnected. This means that any transactions submitted by the -+ * client will never receive a reply (although it's possible that some of -+ * them were actually committed). This event has no associated data. -+ * -+ * - "Locked": The server granted the lock we requested. -+ * -+ * - "Update": The server sent an update to one or more monitored tables. -+ * The client can use the associated data to update its idea of the -+ * snapshot. -+ * -+ * - "Transaction reply": The server sent a reply to a transaction sent by -+ * the client using ovsdb_cs_send_transaction(). -+ */ -+struct ovsdb_cs_event { -+ struct ovs_list list_node; -+ -+ enum ovsdb_cs_event_type { -+ OVSDB_CS_EVENT_TYPE_RECONNECT, /* Connection lost. */ -+ OVSDB_CS_EVENT_TYPE_LOCKED, /* Got the lock we wanted. */ -+ OVSDB_CS_EVENT_TYPE_UPDATE, /* Received update notification. */ -+ OVSDB_CS_EVENT_TYPE_TXN_REPLY, /* Received reply to transaction. */ -+ } type; -+ -+ union { -+ /* Represents a or that contains -+ * either the initial data in a monitor reply or a delta received in an -+ * update notification. The client can use this to update its database -+ * replica. -+ * -+ * If 'clear' is true, then the client should first clear its idea of -+ * what's in the replica before applying the update; otherwise, it's an -+ * incremental update. -+ * -+ * If 'monitor_reply' is true, then this comes from a monitor reply. -+ * This doesn't have real semantic meaning, but it allows the caller -+ * to imitate the exact behavior of previous versions of code that -+ * behaved differently on updates from monitor replies vs. updates. -+ * -+ * 'table-updates' is a if 'version' if 1, otherwise a -+ * . The client can use ovsdb_cs_parse_table_updates() -+ * to parse the update. -+ */ -+ struct ovsdb_cs_update_event { -+ bool clear; -+ bool monitor_reply; -+ struct json *table_updates; -+ int version; -+ } update; -+ -+ /* The "result" member from a transaction reply. The transaction is -+ * one sent by the client using ovsdb_cs_send_transaction(). The -+ * client can match 'txn_reply->id' against the ID in a transaction it -+ * sent. */ -+ struct jsonrpc_msg *txn_reply; -+ }; -+}; -+void ovsdb_cs_event_destroy(struct ovsdb_cs_event *); -+ -+/* Lifecycle. */ -+struct ovsdb_cs *ovsdb_cs_create(const char *database, int max_version, -+ const struct ovsdb_cs_ops *ops, -+ void *ops_aux); -+void ovsdb_cs_destroy(struct ovsdb_cs *); -+ -+void ovsdb_cs_run(struct ovsdb_cs *, struct ovs_list *events); -+void ovsdb_cs_wait(struct ovsdb_cs *); -+ -+/* Network connection. */ -+void ovsdb_cs_set_remote(struct ovsdb_cs *, const char *remote, bool retry); -+ -+void ovsdb_cs_enable_reconnect(struct ovsdb_cs *); -+void ovsdb_cs_force_reconnect(struct ovsdb_cs *); -+void ovsdb_cs_flag_inconsistency(struct ovsdb_cs *); -+ -+bool ovsdb_cs_is_alive(const struct ovsdb_cs *); -+bool ovsdb_cs_is_connected(const struct ovsdb_cs *); -+int ovsdb_cs_get_last_error(const struct ovsdb_cs *); -+ -+void ovsdb_cs_set_probe_interval(const struct ovsdb_cs *, int probe_interval); -+ -+/* Conditional monitoring (specifying that only rows matching particular -+ * criteria should be monitored). -+ * -+ * Some database servers don't support conditional monitoring; in that case, -+ * the client will get all the rows. */ -+unsigned int ovsdb_cs_set_condition(struct ovsdb_cs *, const char *table, -+ const struct json *condition); -+unsigned int ovsdb_cs_get_condition_seqno(const struct ovsdb_cs *); -+ -+/* Clustered servers. */ -+void ovsdb_cs_set_leader_only(struct ovsdb_cs *, bool leader_only); -+void ovsdb_cs_set_shuffle_remotes(struct ovsdb_cs *, bool shuffle); -+void ovsdb_cs_reset_min_index(struct ovsdb_cs *); -+ -+/* Database locks. */ -+void ovsdb_cs_set_lock(struct ovsdb_cs *, const char *lock_name); -+const char *ovsdb_cs_get_lock(const struct ovsdb_cs *); -+bool ovsdb_cs_has_lock(const struct ovsdb_cs *); -+bool ovsdb_cs_is_lock_contended(const struct ovsdb_cs *); -+ -+/* Transactions. */ -+bool ovsdb_cs_may_send_transaction(const struct ovsdb_cs *); -+struct json *ovsdb_cs_send_transaction(struct ovsdb_cs *, struct json *ops) -+ OVS_WARN_UNUSED_RESULT; -+bool ovsdb_cs_forget_transaction(struct ovsdb_cs *, const struct json *); -+ -+/* Helper for partially parsing the or that -+ * appear in struct ovsdb_cs_update_event. The helper leaves the data in JSON -+ * format, so it doesn't need to know column types. */ -+ -+/* The kind of change to a row. */ -+enum ovsdb_cs_row_update_type { -+ OVSDB_CS_ROW_DELETE, /* Row deletion. */ -+ OVSDB_CS_ROW_INSERT, /* Row insertion. */ -+ OVSDB_CS_ROW_UPDATE, /* Replacement of data within a row. */ -+ OVSDB_CS_ROW_XOR /* diff application. */ -+}; -+ -+/* Partially parsed or . */ -+struct ovsdb_cs_row_update { -+ struct uuid row_uuid; /* Row's _uuid. */ -+ enum ovsdb_cs_row_update_type type; /* Type of change. */ -+ const struct shash *columns; /* Map from column name to json data. */ -+}; -+ -+/* Partially parsed or . */ -+struct ovsdb_cs_table_update { -+ const char *table_name; -+ struct ovsdb_cs_row_update *row_updates; -+ size_t n; -+}; -+ -+struct ovsdb_cs_db_update { -+ struct ovsdb_cs_table_update *table_updates; -+ size_t n; -+}; -+ -+struct ovsdb_error *ovsdb_cs_parse_db_update( -+ const struct json *table_updates, int version, -+ struct ovsdb_cs_db_update **db_updatep) -+ OVS_WARN_UNUSED_RESULT; -+void ovsdb_cs_db_update_destroy(struct ovsdb_cs_db_update *); -+const struct ovsdb_cs_table_update *ovsdb_cs_db_update_find_table( -+ const struct ovsdb_cs_db_update *, const char *table_name); -+ -+/* Simple parsing of OVSDB schemas for use by ovsdb_cs clients. */ -+ -+struct shash *ovsdb_cs_parse_schema(const struct json *schema_json); -+void ovsdb_cs_free_schema(struct shash *schema); -+ -+#ifdef __cplusplus -+} // extern "C" -+#endif -+ -+#endif /* ovsdb-cs.h */ -Index: openvswitch-2.17.2/lib/ovsdb-data.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-data.h -+++ /dev/null -@@ -1,339 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011, 2012, 2015, 2016, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_DATA_H --#define OVSDB_DATA_H 1 -- --#include --#include "openvswitch/compiler.h" --#include "ovsdb-types.h" --#include "openvswitch/json.h" --#include "openvswitch/shash.h" --#include "util.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --#define MAX_OVSDB_ATOM_RANGE_SIZE 4096 -- --struct ds; --struct ovsdb_symbol_table; --struct smap; -- --static inline struct json * --ovsdb_atom_string_create_nocopy(char *str) --{ -- return json_string_create_nocopy(str); --} -- --static inline struct json * --ovsdb_atom_string_create(const char *str) --{ -- return json_string_create(str); --} -- --/* One value of an atomic type (given by enum ovs_atomic_type). */ --union ovsdb_atom { -- int64_t integer; -- double real; -- bool boolean; -- struct json *s; -- struct uuid uuid; --}; -- --void ovsdb_atom_init_default(union ovsdb_atom *, enum ovsdb_atomic_type); --const union ovsdb_atom *ovsdb_atom_default(enum ovsdb_atomic_type); --bool ovsdb_atom_is_default(const union ovsdb_atom *, enum ovsdb_atomic_type); --void ovsdb_atom_clone(union ovsdb_atom *, const union ovsdb_atom *, -- enum ovsdb_atomic_type); --void ovsdb_atom_swap(union ovsdb_atom *, union ovsdb_atom *); -- --/* Returns false if ovsdb_atom_destroy() is a no-op when it is applied to an -- * initialized atom of the given 'type', true if ovsdb_atom_destroy() actually -- * does something. -- * -- * This can be used to avoid calling ovsdb_atom_destroy() for each element in -- * an array of homogeneous atoms. (It's not worthwhile for a single atom.) */ --static inline bool --ovsdb_atom_needs_destruction(enum ovsdb_atomic_type type) --{ -- return type == OVSDB_TYPE_STRING; --} -- --/* Frees the contents of 'atom', which must have the specified 'type'. -- * -- * This does not actually call free(atom). If necessary, the caller must be -- * responsible for that. */ --static inline void --ovsdb_atom_destroy(union ovsdb_atom *atom, enum ovsdb_atomic_type type) --{ -- if (type == OVSDB_TYPE_STRING) { -- json_destroy(atom->s); -- } --} -- --uint32_t ovsdb_atom_hash(const union ovsdb_atom *, enum ovsdb_atomic_type, -- uint32_t basis); -- --int ovsdb_atom_compare_3way(const union ovsdb_atom *, -- const union ovsdb_atom *, -- enum ovsdb_atomic_type); -- --/* Returns true if 'a' and 'b', which are both of type 'type', has the same -- * contents, false if their contents differ. */ --static inline bool ovsdb_atom_equals(const union ovsdb_atom *a, -- const union ovsdb_atom *b, -- enum ovsdb_atomic_type type) --{ -- return !ovsdb_atom_compare_3way(a, b, type); --} -- --struct ovsdb_error *ovsdb_atom_from_json(union ovsdb_atom *, -- const struct ovsdb_base_type *, -- const struct json *, -- struct ovsdb_symbol_table *) -- OVS_WARN_UNUSED_RESULT; --struct json *ovsdb_atom_to_json(const union ovsdb_atom *, -- enum ovsdb_atomic_type); -- --char *ovsdb_atom_from_string(union ovsdb_atom *, union ovsdb_atom **, -- const struct ovsdb_base_type *, const char *, -- struct ovsdb_symbol_table *) -- OVS_WARN_UNUSED_RESULT; --void ovsdb_atom_to_string(const union ovsdb_atom *, enum ovsdb_atomic_type, -- struct ds *); --void ovsdb_atom_to_bare(const union ovsdb_atom *, enum ovsdb_atomic_type, -- struct ds *); -- --struct ovsdb_error *ovsdb_atom_check_constraints( -- const union ovsdb_atom *, const struct ovsdb_base_type *) -- OVS_WARN_UNUSED_RESULT; -- --/* An instance of an OVSDB type (given by struct ovsdb_type). -- * -- * - The 'keys' must be unique and in sorted order. Most functions that modify -- * an ovsdb_datum maintain these invariants. Functions that don't maintain -- * the invariants have names that end in "_unsafe". Use ovsdb_datum_sort() -- * to check and restore these invariants. -- * -- * - 'n' is constrained by the ovsdb_type's 'n_min' and 'n_max'. -- * -- * If 'n' is nonzero, then 'keys' points to an array of 'n' atoms of the type -- * specified by the ovsdb_type's 'key_type'. (Otherwise, 'keys' should be -- * null.) -- * -- * If 'n' is nonzero and the ovsdb_type's 'value_type' is not -- * OVSDB_TYPE_VOID, then 'values' points to an array of 'n' atoms of the type -- * specified by the 'value_type'. (Otherwise, 'values' should be null.) -- * -- * Thus, for 'n' > 0, 'keys' will always be nonnull and 'values' will be -- * nonnull only for "map" types. -- */ --struct ovsdb_datum { -- unsigned int n; /* Number of 'keys' and 'values'. */ -- union ovsdb_atom *keys; /* Each of the ovsdb_type's 'key_type'. */ -- union ovsdb_atom *values; /* Each of the ovsdb_type's 'value_type'. */ --}; --#define OVSDB_DATUM_INITIALIZER { 0, NULL, NULL } -- --/* Basics. */ --void ovsdb_datum_init_empty(struct ovsdb_datum *); --void ovsdb_datum_init_default(struct ovsdb_datum *, const struct ovsdb_type *); --bool ovsdb_datum_is_default(const struct ovsdb_datum *, -- const struct ovsdb_type *); --const struct ovsdb_datum *ovsdb_datum_default(const struct ovsdb_type *); --void ovsdb_datum_clone(struct ovsdb_datum *, const struct ovsdb_datum *, -- const struct ovsdb_type *); --void ovsdb_datum_destroy(struct ovsdb_datum *, const struct ovsdb_type *); --void ovsdb_datum_swap(struct ovsdb_datum *, struct ovsdb_datum *); -- --/* Checking and maintaining invariants. */ --struct ovsdb_error *ovsdb_datum_sort(struct ovsdb_datum *, -- enum ovsdb_atomic_type key_type) -- OVS_WARN_UNUSED_RESULT; -- --void ovsdb_datum_sort_assert(struct ovsdb_datum *, -- enum ovsdb_atomic_type key_type); -- --size_t ovsdb_datum_sort_unique(struct ovsdb_datum *, -- enum ovsdb_atomic_type key_type, -- enum ovsdb_atomic_type value_type); -- --struct ovsdb_error *ovsdb_datum_check_constraints( -- const struct ovsdb_datum *, const struct ovsdb_type *) -- OVS_WARN_UNUSED_RESULT; -- --/* Type conversion. */ --struct ovsdb_error *ovsdb_datum_from_json(struct ovsdb_datum *, -- const struct ovsdb_type *, -- const struct json *, -- struct ovsdb_symbol_table *) -- OVS_WARN_UNUSED_RESULT; --struct ovsdb_error *ovsdb_transient_datum_from_json( -- struct ovsdb_datum *, -- const struct ovsdb_type *, -- const struct json *) -- OVS_WARN_UNUSED_RESULT; --struct ovsdb_error * --ovsdb_unconstrained_datum_from_json(struct ovsdb_datum *, -- const struct ovsdb_type *, -- const struct json *) -- OVS_WARN_UNUSED_RESULT; --struct json *ovsdb_datum_to_json(const struct ovsdb_datum *, -- const struct ovsdb_type *); -- --char *ovsdb_datum_from_string(struct ovsdb_datum *, -- const struct ovsdb_type *, const char *, -- struct ovsdb_symbol_table *) -- OVS_WARN_UNUSED_RESULT; --void ovsdb_datum_to_string(const struct ovsdb_datum *, -- const struct ovsdb_type *, struct ds *); --void ovsdb_datum_to_bare(const struct ovsdb_datum *, -- const struct ovsdb_type *, struct ds *); -- --void ovsdb_datum_from_smap(struct ovsdb_datum *, const struct smap *); -- --struct ovsdb_error *ovsdb_datum_convert(struct ovsdb_datum *dst, -- const struct ovsdb_type *dst_type, -- const struct ovsdb_datum *src, -- const struct ovsdb_type *src_type) -- OVS_WARN_UNUSED_RESULT; -- --/* Comparison. */ --uint32_t ovsdb_datum_hash(const struct ovsdb_datum *, -- const struct ovsdb_type *, uint32_t basis); --int ovsdb_datum_compare_3way(const struct ovsdb_datum *, -- const struct ovsdb_datum *, -- const struct ovsdb_type *); --bool ovsdb_datum_equals(const struct ovsdb_datum *, -- const struct ovsdb_datum *, -- const struct ovsdb_type *); -- --/* Search. */ --bool ovsdb_datum_find_key(const struct ovsdb_datum *, -- const union ovsdb_atom *key, -- enum ovsdb_atomic_type key_type, -- unsigned int *pos); --unsigned int ovsdb_datum_find_key_value(const struct ovsdb_datum *, -- const union ovsdb_atom *key, -- enum ovsdb_atomic_type key_type, -- const union ovsdb_atom *value, -- enum ovsdb_atomic_type value_type); -- --/* Set operations. */ --bool ovsdb_datum_includes_all(const struct ovsdb_datum *, -- const struct ovsdb_datum *, -- const struct ovsdb_type *); --bool ovsdb_datum_excludes_all(const struct ovsdb_datum *, -- const struct ovsdb_datum *, -- const struct ovsdb_type *); --void ovsdb_datum_union(struct ovsdb_datum *, -- const struct ovsdb_datum *, -- const struct ovsdb_type *); --void ovsdb_datum_subtract(struct ovsdb_datum *a, -- const struct ovsdb_type *a_type, -- const struct ovsdb_datum *b, -- const struct ovsdb_type *b_type); -- --/* Generate and apply diffs */ --void ovsdb_datum_added_removed(struct ovsdb_datum *added, -- struct ovsdb_datum *removed, -- const struct ovsdb_datum *old, -- const struct ovsdb_datum *new, -- const struct ovsdb_type *type); -- --void ovsdb_datum_diff(struct ovsdb_datum *diff, -- const struct ovsdb_datum *old_datum, -- const struct ovsdb_datum *new_datum, -- const struct ovsdb_type *type); -- --struct ovsdb_error *ovsdb_datum_apply_diff(struct ovsdb_datum *new_datum, -- const struct ovsdb_datum *old_datum, -- const struct ovsdb_datum *diff, -- const struct ovsdb_type *type) --OVS_WARN_UNUSED_RESULT; -- --struct ovsdb_error * ovsdb_datum_apply_diff_in_place( -- struct ovsdb_datum *a, -- const struct ovsdb_datum *diff, -- const struct ovsdb_type *type) --OVS_WARN_UNUSED_RESULT; -- --/* Raw operations that may not maintain the invariants. */ --void ovsdb_datum_remove_unsafe(struct ovsdb_datum *, size_t idx, -- const struct ovsdb_type *); --void ovsdb_datum_add_unsafe(struct ovsdb_datum *, -- const union ovsdb_atom *key, -- const union ovsdb_atom *value, -- const struct ovsdb_type *, -- const union ovsdb_atom *range_end_atom); --void ovsdb_datum_add_from_index_unsafe(struct ovsdb_datum *dst, -- const struct ovsdb_datum *src, -- size_t idx, -- const struct ovsdb_type *type); -- --/* Transactions with named-uuid row names. */ --struct json *ovsdb_datum_to_json_with_row_names(const struct ovsdb_datum *, -- const struct ovsdb_type *); --char *ovsdb_data_row_name(const struct uuid *); -- --/* Type checking. */ --static inline bool --ovsdb_datum_conforms_to_type(const struct ovsdb_datum *datum, -- const struct ovsdb_type *type) --{ -- return datum->n >= type->n_min && datum->n <= type->n_max; --} -- --/* A table mapping from names to data items. Currently the data items are -- * always UUIDs; perhaps this will be expanded in the future. */ -- --struct ovsdb_symbol_table { -- struct shash sh; /* Maps from name to struct ovsdb_symbol *. */ --}; -- --struct ovsdb_symbol { -- struct uuid uuid; /* The UUID that the symbol represents. */ -- bool created; /* Already used to create row? */ -- bool strong_ref; /* Parsed a strong reference to this row? */ -- bool weak_ref; /* Parsed a weak reference to this row? */ --}; -- --struct ovsdb_symbol_table *ovsdb_symbol_table_create(void); --void ovsdb_symbol_table_destroy(struct ovsdb_symbol_table *); --struct ovsdb_symbol *ovsdb_symbol_table_get(const struct ovsdb_symbol_table *, -- const char *name); --struct ovsdb_symbol *ovsdb_symbol_table_put(struct ovsdb_symbol_table *, -- const char *name, -- const struct uuid *, bool used); --struct ovsdb_symbol *ovsdb_symbol_table_insert(struct ovsdb_symbol_table *, -- const char *name); -- --/* Tokenization -- * -- * Used by ovsdb_atom_from_string() and ovsdb_datum_from_string(). */ -- --char *ovsdb_token_parse(const char **, char **outp) OVS_WARN_UNUSED_RESULT; --bool ovsdb_token_is_delim(unsigned char); -- --struct ovsdb_error *ovsdb_atom_range_check_size(int64_t range_start, -- int64_t range_end); -- --#ifdef __cplusplus --} --#endif -- --#endif /* ovsdb-data.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-data.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-data.h -@@ -0,0 +1,339 @@ -+/* Copyright (c) 2009, 2010, 2011, 2012, 2015, 2016, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_DATA_H -+#define OVSDB_DATA_H 1 -+ -+#include -+#include "openvswitch/compiler.h" -+#include "openvswitch/ovsdb-types.h" -+#include "openvswitch/json.h" -+#include "openvswitch/shash.h" -+#include "internal/util.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define MAX_OVSDB_ATOM_RANGE_SIZE 4096 -+ -+struct ds; -+struct ovsdb_symbol_table; -+struct smap; -+ -+static inline struct json * -+ovsdb_atom_string_create_nocopy(char *str) -+{ -+ return json_string_create_nocopy(str); -+} -+ -+static inline struct json * -+ovsdb_atom_string_create(const char *str) -+{ -+ return json_string_create(str); -+} -+ -+/* One value of an atomic type (given by enum ovs_atomic_type). */ -+union ovsdb_atom { -+ int64_t integer; -+ double real; -+ bool boolean; -+ struct json *s; -+ struct uuid uuid; -+}; -+ -+void ovsdb_atom_init_default(union ovsdb_atom *, enum ovsdb_atomic_type); -+const union ovsdb_atom *ovsdb_atom_default(enum ovsdb_atomic_type); -+bool ovsdb_atom_is_default(const union ovsdb_atom *, enum ovsdb_atomic_type); -+void ovsdb_atom_clone(union ovsdb_atom *, const union ovsdb_atom *, -+ enum ovsdb_atomic_type); -+void ovsdb_atom_swap(union ovsdb_atom *, union ovsdb_atom *); -+ -+/* Returns false if ovsdb_atom_destroy() is a no-op when it is applied to an -+ * initialized atom of the given 'type', true if ovsdb_atom_destroy() actually -+ * does something. -+ * -+ * This can be used to avoid calling ovsdb_atom_destroy() for each element in -+ * an array of homogeneous atoms. (It's not worthwhile for a single atom.) */ -+static inline bool -+ovsdb_atom_needs_destruction(enum ovsdb_atomic_type type) -+{ -+ return type == OVSDB_TYPE_STRING; -+} -+ -+/* Frees the contents of 'atom', which must have the specified 'type'. -+ * -+ * This does not actually call free(atom). If necessary, the caller must be -+ * responsible for that. */ -+static inline void -+ovsdb_atom_destroy(union ovsdb_atom *atom, enum ovsdb_atomic_type type) -+{ -+ if (type == OVSDB_TYPE_STRING) { -+ json_destroy(atom->s); -+ } -+} -+ -+uint32_t ovsdb_atom_hash(const union ovsdb_atom *, enum ovsdb_atomic_type, -+ uint32_t basis); -+ -+int ovsdb_atom_compare_3way(const union ovsdb_atom *, -+ const union ovsdb_atom *, -+ enum ovsdb_atomic_type); -+ -+/* Returns true if 'a' and 'b', which are both of type 'type', has the same -+ * contents, false if their contents differ. */ -+static inline bool ovsdb_atom_equals(const union ovsdb_atom *a, -+ const union ovsdb_atom *b, -+ enum ovsdb_atomic_type type) -+{ -+ return !ovsdb_atom_compare_3way(a, b, type); -+} -+ -+struct ovsdb_error *ovsdb_atom_from_json(union ovsdb_atom *, -+ const struct ovsdb_base_type *, -+ const struct json *, -+ struct ovsdb_symbol_table *) -+ OVS_WARN_UNUSED_RESULT; -+struct json *ovsdb_atom_to_json(const union ovsdb_atom *, -+ enum ovsdb_atomic_type); -+ -+char *ovsdb_atom_from_string(union ovsdb_atom *, union ovsdb_atom **, -+ const struct ovsdb_base_type *, const char *, -+ struct ovsdb_symbol_table *) -+ OVS_WARN_UNUSED_RESULT; -+void ovsdb_atom_to_string(const union ovsdb_atom *, enum ovsdb_atomic_type, -+ struct ds *); -+void ovsdb_atom_to_bare(const union ovsdb_atom *, enum ovsdb_atomic_type, -+ struct ds *); -+ -+struct ovsdb_error *ovsdb_atom_check_constraints( -+ const union ovsdb_atom *, const struct ovsdb_base_type *) -+ OVS_WARN_UNUSED_RESULT; -+ -+/* An instance of an OVSDB type (given by struct ovsdb_type). -+ * -+ * - The 'keys' must be unique and in sorted order. Most functions that modify -+ * an ovsdb_datum maintain these invariants. Functions that don't maintain -+ * the invariants have names that end in "_unsafe". Use ovsdb_datum_sort() -+ * to check and restore these invariants. -+ * -+ * - 'n' is constrained by the ovsdb_type's 'n_min' and 'n_max'. -+ * -+ * If 'n' is nonzero, then 'keys' points to an array of 'n' atoms of the type -+ * specified by the ovsdb_type's 'key_type'. (Otherwise, 'keys' should be -+ * null.) -+ * -+ * If 'n' is nonzero and the ovsdb_type's 'value_type' is not -+ * OVSDB_TYPE_VOID, then 'values' points to an array of 'n' atoms of the type -+ * specified by the 'value_type'. (Otherwise, 'values' should be null.) -+ * -+ * Thus, for 'n' > 0, 'keys' will always be nonnull and 'values' will be -+ * nonnull only for "map" types. -+ */ -+struct ovsdb_datum { -+ unsigned int n; /* Number of 'keys' and 'values'. */ -+ union ovsdb_atom *keys; /* Each of the ovsdb_type's 'key_type'. */ -+ union ovsdb_atom *values; /* Each of the ovsdb_type's 'value_type'. */ -+}; -+#define OVSDB_DATUM_INITIALIZER { 0, NULL, NULL } -+ -+/* Basics. */ -+void ovsdb_datum_init_empty(struct ovsdb_datum *); -+void ovsdb_datum_init_default(struct ovsdb_datum *, const struct ovsdb_type *); -+bool ovsdb_datum_is_default(const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+const struct ovsdb_datum *ovsdb_datum_default(const struct ovsdb_type *); -+void ovsdb_datum_clone(struct ovsdb_datum *, const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+void ovsdb_datum_destroy(struct ovsdb_datum *, const struct ovsdb_type *); -+void ovsdb_datum_swap(struct ovsdb_datum *, struct ovsdb_datum *); -+ -+/* Checking and maintaining invariants. */ -+struct ovsdb_error *ovsdb_datum_sort(struct ovsdb_datum *, -+ enum ovsdb_atomic_type key_type) -+ OVS_WARN_UNUSED_RESULT; -+ -+void ovsdb_datum_sort_assert(struct ovsdb_datum *, -+ enum ovsdb_atomic_type key_type); -+ -+size_t ovsdb_datum_sort_unique(struct ovsdb_datum *, -+ enum ovsdb_atomic_type key_type, -+ enum ovsdb_atomic_type value_type); -+ -+struct ovsdb_error *ovsdb_datum_check_constraints( -+ const struct ovsdb_datum *, const struct ovsdb_type *) -+ OVS_WARN_UNUSED_RESULT; -+ -+/* Type conversion. */ -+struct ovsdb_error *ovsdb_datum_from_json(struct ovsdb_datum *, -+ const struct ovsdb_type *, -+ const struct json *, -+ struct ovsdb_symbol_table *) -+ OVS_WARN_UNUSED_RESULT; -+struct ovsdb_error *ovsdb_transient_datum_from_json( -+ struct ovsdb_datum *, -+ const struct ovsdb_type *, -+ const struct json *) -+ OVS_WARN_UNUSED_RESULT; -+struct ovsdb_error * -+ovsdb_unconstrained_datum_from_json(struct ovsdb_datum *, -+ const struct ovsdb_type *, -+ const struct json *) -+ OVS_WARN_UNUSED_RESULT; -+struct json *ovsdb_datum_to_json(const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+ -+char *ovsdb_datum_from_string(struct ovsdb_datum *, -+ const struct ovsdb_type *, const char *, -+ struct ovsdb_symbol_table *) -+ OVS_WARN_UNUSED_RESULT; -+void ovsdb_datum_to_string(const struct ovsdb_datum *, -+ const struct ovsdb_type *, struct ds *); -+void ovsdb_datum_to_bare(const struct ovsdb_datum *, -+ const struct ovsdb_type *, struct ds *); -+ -+void ovsdb_datum_from_smap(struct ovsdb_datum *, const struct smap *); -+ -+struct ovsdb_error *ovsdb_datum_convert(struct ovsdb_datum *dst, -+ const struct ovsdb_type *dst_type, -+ const struct ovsdb_datum *src, -+ const struct ovsdb_type *src_type) -+ OVS_WARN_UNUSED_RESULT; -+ -+/* Comparison. */ -+uint32_t ovsdb_datum_hash(const struct ovsdb_datum *, -+ const struct ovsdb_type *, uint32_t basis); -+int ovsdb_datum_compare_3way(const struct ovsdb_datum *, -+ const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+bool ovsdb_datum_equals(const struct ovsdb_datum *, -+ const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+ -+/* Search. */ -+bool ovsdb_datum_find_key(const struct ovsdb_datum *, -+ const union ovsdb_atom *key, -+ enum ovsdb_atomic_type key_type, -+ unsigned int *pos); -+unsigned int ovsdb_datum_find_key_value(const struct ovsdb_datum *, -+ const union ovsdb_atom *key, -+ enum ovsdb_atomic_type key_type, -+ const union ovsdb_atom *value, -+ enum ovsdb_atomic_type value_type); -+ -+/* Set operations. */ -+bool ovsdb_datum_includes_all(const struct ovsdb_datum *, -+ const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+bool ovsdb_datum_excludes_all(const struct ovsdb_datum *, -+ const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+void ovsdb_datum_union(struct ovsdb_datum *, -+ const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+void ovsdb_datum_subtract(struct ovsdb_datum *a, -+ const struct ovsdb_type *a_type, -+ const struct ovsdb_datum *b, -+ const struct ovsdb_type *b_type); -+ -+/* Generate and apply diffs */ -+void ovsdb_datum_added_removed(struct ovsdb_datum *added, -+ struct ovsdb_datum *removed, -+ const struct ovsdb_datum *old, -+ const struct ovsdb_datum *new, -+ const struct ovsdb_type *type); -+ -+void ovsdb_datum_diff(struct ovsdb_datum *diff, -+ const struct ovsdb_datum *old_datum, -+ const struct ovsdb_datum *new_datum, -+ const struct ovsdb_type *type); -+ -+struct ovsdb_error *ovsdb_datum_apply_diff(struct ovsdb_datum *new_datum, -+ const struct ovsdb_datum *old_datum, -+ const struct ovsdb_datum *diff, -+ const struct ovsdb_type *type) -+OVS_WARN_UNUSED_RESULT; -+ -+struct ovsdb_error * ovsdb_datum_apply_diff_in_place( -+ struct ovsdb_datum *a, -+ const struct ovsdb_datum *diff, -+ const struct ovsdb_type *type) -+OVS_WARN_UNUSED_RESULT; -+ -+/* Raw operations that may not maintain the invariants. */ -+void ovsdb_datum_remove_unsafe(struct ovsdb_datum *, size_t idx, -+ const struct ovsdb_type *); -+void ovsdb_datum_add_unsafe(struct ovsdb_datum *, -+ const union ovsdb_atom *key, -+ const union ovsdb_atom *value, -+ const struct ovsdb_type *, -+ const union ovsdb_atom *range_end_atom); -+void ovsdb_datum_add_from_index_unsafe(struct ovsdb_datum *dst, -+ const struct ovsdb_datum *src, -+ size_t idx, -+ const struct ovsdb_type *type); -+ -+/* Transactions with named-uuid row names. */ -+struct json *ovsdb_datum_to_json_with_row_names(const struct ovsdb_datum *, -+ const struct ovsdb_type *); -+char *ovsdb_data_row_name(const struct uuid *); -+ -+/* Type checking. */ -+static inline bool -+ovsdb_datum_conforms_to_type(const struct ovsdb_datum *datum, -+ const struct ovsdb_type *type) -+{ -+ return datum->n >= type->n_min && datum->n <= type->n_max; -+} -+ -+/* A table mapping from names to data items. Currently the data items are -+ * always UUIDs; perhaps this will be expanded in the future. */ -+ -+struct ovsdb_symbol_table { -+ struct shash sh; /* Maps from name to struct ovsdb_symbol *. */ -+}; -+ -+struct ovsdb_symbol { -+ struct uuid uuid; /* The UUID that the symbol represents. */ -+ bool created; /* Already used to create row? */ -+ bool strong_ref; /* Parsed a strong reference to this row? */ -+ bool weak_ref; /* Parsed a weak reference to this row? */ -+}; -+ -+struct ovsdb_symbol_table *ovsdb_symbol_table_create(void); -+void ovsdb_symbol_table_destroy(struct ovsdb_symbol_table *); -+struct ovsdb_symbol *ovsdb_symbol_table_get(const struct ovsdb_symbol_table *, -+ const char *name); -+struct ovsdb_symbol *ovsdb_symbol_table_put(struct ovsdb_symbol_table *, -+ const char *name, -+ const struct uuid *, bool used); -+struct ovsdb_symbol *ovsdb_symbol_table_insert(struct ovsdb_symbol_table *, -+ const char *name); -+ -+/* Tokenization -+ * -+ * Used by ovsdb_atom_from_string() and ovsdb_datum_from_string(). */ -+ -+char *ovsdb_token_parse(const char **, char **outp) OVS_WARN_UNUSED_RESULT; -+bool ovsdb_token_is_delim(unsigned char); -+ -+struct ovsdb_error *ovsdb_atom_range_check_size(int64_t range_start, -+ int64_t range_end); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* ovsdb-data.h */ -Index: openvswitch-2.17.2/lib/ovsdb-error.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-error.h -+++ /dev/null -@@ -1,75 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011, 2016, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_ERROR_H --#define OVSDB_ERROR_H 1 -- --#include "openvswitch/compiler.h" -- --struct json; -- --struct ovsdb_error *ovsdb_error(const char *tag, const char *details, ...) -- OVS_PRINTF_FORMAT(2, 3) -- OVS_WARN_UNUSED_RESULT; --struct ovsdb_error *ovsdb_io_error(int error, const char *details, ...) -- OVS_PRINTF_FORMAT(2, 3) -- OVS_WARN_UNUSED_RESULT; --struct ovsdb_error *ovsdb_syntax_error(const struct json *, const char *tag, -- const char *details, ...) -- OVS_PRINTF_FORMAT(3, 4) -- OVS_WARN_UNUSED_RESULT; -- --struct ovsdb_error *ovsdb_wrap_error(struct ovsdb_error *error, -- const char *details, ...) -- OVS_PRINTF_FORMAT(2, 3); -- --struct ovsdb_error *ovsdb_internal_error(struct ovsdb_error *error, -- const char *file, int line, -- const char *details, ...) -- OVS_PRINTF_FORMAT(4, 5) -- OVS_WARN_UNUSED_RESULT; -- --struct ovsdb_error *ovsdb_perm_error(const char *details, ...) -- OVS_PRINTF_FORMAT(1, 2) -- OVS_WARN_UNUSED_RESULT; -- --/* Returns a pointer to an ovsdb_error that represents an internal error for -- * the current file name and line number with MSG as the associated message. -- * The caller is responsible for freeing the internal error. */ --#define OVSDB_BUG(MSG) \ -- ovsdb_internal_error(NULL, __FILE__, __LINE__, "%s", MSG) -- --/* Returns a pointer to an ovsdb_error that represents an internal error for -- * the current file name and line number, with MSG as the associated message. -- * If ERROR is nonnull then the internal error is wrapped around ERROR. Takes -- * ownership of ERROR. The caller is responsible for freeing the returned -- * error. */ --#define OVSDB_WRAP_BUG(MSG, ERROR) \ -- ovsdb_internal_error(ERROR, __FILE__, __LINE__, "%s", MSG) -- --void ovsdb_error_destroy(struct ovsdb_error *); --struct ovsdb_error *ovsdb_error_clone(const struct ovsdb_error *) -- OVS_WARN_UNUSED_RESULT; -- --char *ovsdb_error_to_string(const struct ovsdb_error *); --char *ovsdb_error_to_string_free(struct ovsdb_error *); --struct json *ovsdb_error_to_json(const struct ovsdb_error *); --struct json *ovsdb_error_to_json_free(struct ovsdb_error *); -- --const char *ovsdb_error_get_tag(const struct ovsdb_error *); -- --void ovsdb_error_assert(struct ovsdb_error *); -- --#endif /* ovsdb-error.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-error.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-error.h -@@ -0,0 +1,83 @@ -+/* Copyright (c) 2009, 2010, 2011, 2016, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_ERROR_H -+#define OVSDB_ERROR_H 1 -+ -+#include "openvswitch/compiler.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct json; -+ -+struct ovsdb_error *ovsdb_error(const char *tag, const char *details, ...) -+ OVS_PRINTF_FORMAT(2, 3) -+ OVS_WARN_UNUSED_RESULT; -+struct ovsdb_error *ovsdb_io_error(int error, const char *details, ...) -+ OVS_PRINTF_FORMAT(2, 3) -+ OVS_WARN_UNUSED_RESULT; -+struct ovsdb_error *ovsdb_syntax_error(const struct json *, const char *tag, -+ const char *details, ...) -+ OVS_PRINTF_FORMAT(3, 4) -+ OVS_WARN_UNUSED_RESULT; -+ -+struct ovsdb_error *ovsdb_wrap_error(struct ovsdb_error *error, -+ const char *details, ...) -+ OVS_PRINTF_FORMAT(2, 3); -+ -+struct ovsdb_error *ovsdb_internal_error(struct ovsdb_error *error, -+ const char *file, int line, -+ const char *details, ...) -+ OVS_PRINTF_FORMAT(4, 5) -+ OVS_WARN_UNUSED_RESULT; -+ -+struct ovsdb_error *ovsdb_perm_error(const char *details, ...) -+ OVS_PRINTF_FORMAT(1, 2) -+ OVS_WARN_UNUSED_RESULT; -+ -+/* Returns a pointer to an ovsdb_error that represents an internal error for -+ * the current file name and line number with MSG as the associated message. -+ * The caller is responsible for freeing the internal error. */ -+#define OVSDB_BUG(MSG) \ -+ ovsdb_internal_error(NULL, __FILE__, __LINE__, "%s", MSG) -+ -+/* Returns a pointer to an ovsdb_error that represents an internal error for -+ * the current file name and line number, with MSG as the associated message. -+ * If ERROR is nonnull then the internal error is wrapped around ERROR. Takes -+ * ownership of ERROR. The caller is responsible for freeing the returned -+ * error. */ -+#define OVSDB_WRAP_BUG(MSG, ERROR) \ -+ ovsdb_internal_error(ERROR, __FILE__, __LINE__, "%s", MSG) -+ -+void ovsdb_error_destroy(struct ovsdb_error *); -+struct ovsdb_error *ovsdb_error_clone(const struct ovsdb_error *) -+ OVS_WARN_UNUSED_RESULT; -+ -+char *ovsdb_error_to_string(const struct ovsdb_error *); -+char *ovsdb_error_to_string_free(struct ovsdb_error *); -+struct json *ovsdb_error_to_json(const struct ovsdb_error *); -+struct json *ovsdb_error_to_json_free(struct ovsdb_error *); -+ -+const char *ovsdb_error_get_tag(const struct ovsdb_error *); -+ -+void ovsdb_error_assert(struct ovsdb_error *); -+ -+#ifdef __cplusplus -+} // extern "C" -+#endif -+ -+#endif /* ovsdb-error.h */ -Index: openvswitch-2.17.2/lib/ovsdb-idl-provider.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-idl-provider.h -+++ /dev/null -@@ -1,181 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011, 2012, 2016 Nicira, Inc. -- * Copyright (C) 2016 Hewlett Packard Enterprise Development LP -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_IDL_PROVIDER_H --#define OVSDB_IDL_PROVIDER_H 1 -- --#include "openvswitch/hmap.h" --#include "openvswitch/list.h" --#include "ovsdb-idl.h" --#include "ovsdb-map-op.h" --#include "ovsdb-set-op.h" --#include "ovsdb-types.h" --#include "openvswitch/shash.h" --#include "sset.h" --#include "uuid.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --/* A local copy of a row in an OVSDB table, replicated from an OVSDB server. -- * This structure is used as a header for a larger structure that translates -- * the "struct ovsdb_datum"s into easier-to-use forms, via the ->parse() and -- * ->unparse functions in struct ovsdb_idl_column. (Those functions are -- * generated automatically via ovsdb-idlc.) -- * -- * When no transaction is in progress: -- * -- * - 'old_datum' points to the data committed to the database and currently -- * in the row. -- * -- * - 'new_datum == old_datum'. -- * -- * When a transaction is in progress, the situation is a little different. For -- * a row inserted in the transaction, 'old_datum' is NULL and 'new_datum' -- * points to the row's initial contents. Otherwise: -- * -- * - 'old_datum' points to the data committed to the database and currently -- * in the row. (This is the same as when no transaction is in progress.) -- * -- * - If the transaction does not modify the row, 'new_datum == old_datum'. -- * -- * - If the transaction modifies the row, 'new_datum' points to the -- * modified data. -- * -- * - If the transaction deletes the row, 'new_datum' is NULL. -- * -- * Thus: -- * -- * - 'old_datum' always points to committed data, except that it is NULL if -- * the row is inserted within the current transaction. -- * -- * - 'new_datum' always points to the newest, possibly uncommitted version -- * of the row's data, except that it is NULL if the row is deleted within -- * the current transaction. -- */ --struct ovsdb_idl_row { -- struct hmap_node hmap_node; /* In struct ovsdb_idl_table's 'rows'. */ -- struct uuid uuid; /* Row "_uuid" field. */ -- struct ovs_list src_arcs; /* Forward arcs (ovsdb_idl_arc.src_node). */ -- struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */ -- struct ovsdb_idl_table *table; /* Containing table. */ -- struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */ -- bool parsed; /* Whether the row is parsed. */ -- struct ovs_list reparse_node; /* Rows that needs to be re-parsed due to -- * insertion of a referenced row. */ -- -- /* Transactional data. */ -- struct ovsdb_datum *new_datum; /* Modified data (null to delete row). */ -- unsigned long int *prereqs; /* Bitmap of "old_datum" columns to verify. */ -- unsigned long int *written; /* Bitmap of "new_datum" columns to write. */ -- struct hmap_node txn_node; /* Node in ovsdb_idl_txn's list. */ -- unsigned long int *map_op_written; /* Bitmap of columns pending map ops. */ -- struct map_op_list **map_op_lists; /* Per-column map operations. */ -- unsigned long int *set_op_written; /* Bitmap of columns pending set ops. */ -- struct set_op_list **set_op_lists; /* Per-column set operations. */ -- -- /* Tracking data */ -- unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX]; -- struct ovs_list track_node; /* Rows modified/added/deleted by IDL */ -- unsigned long int *updated; /* Bitmap of columns updated by IDL */ -- struct ovsdb_datum *tracked_old_datum; /* Old deleted data. */ --}; -- --struct ovsdb_idl_column { -- char *name; -- struct ovsdb_type type; -- bool is_mutable; -- bool is_synthetic; -- void (*parse)(struct ovsdb_idl_row *, const struct ovsdb_datum *); -- void (*unparse)(struct ovsdb_idl_row *); --}; -- --struct ovsdb_idl_table_class { -- char *name; -- bool is_root; -- bool is_singleton; -- const struct ovsdb_idl_column *columns; -- size_t n_columns; -- size_t allocation_size; -- void (*row_init)(struct ovsdb_idl_row *); --}; -- --struct ovsdb_idl_table { -- const struct ovsdb_idl_table_class *class_; -- unsigned char *modes; /* OVSDB_IDL_* bitmasks, indexed by column. */ -- bool need_table; /* Monitor table even if no columns are selected -- * for replication. */ -- struct shash columns; /* Contains "const struct ovsdb_idl_column *"s. */ -- struct sset schema_columns; /* Column names from schema. */ -- struct hmap rows; /* Contains "struct ovsdb_idl_row"s. */ -- struct ovsdb_idl *idl; /* Containing IDL instance. */ -- unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX]; -- bool in_server_schema; /* Indicates if this table is in the server schema -- * or not. */ -- struct ovs_list indexes; /* Contains "struct ovsdb_idl_index"s */ -- struct ovs_list track_list; /* Tracked rows (ovsdb_idl_row.track_node). */ --}; -- --struct ovsdb_idl_class { -- const char *database; /* for this database. */ -- const struct ovsdb_idl_table_class *tables; -- size_t n_tables; --}; -- --struct ovsdb_idl_row *ovsdb_idl_get_row_arc( -- struct ovsdb_idl_row *src, -- const struct ovsdb_idl_table_class *dst_table, -- const struct uuid *dst_uuid); -- --void ovsdb_idl_txn_verify(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *); -- --struct ovsdb_idl_txn *ovsdb_idl_txn_get(const struct ovsdb_idl_row *); -- --/* Index internals. */ -- --struct ovsdb_idl_index { -- struct ovs_list node; /* In ->table->indexes. */ -- struct ovsdb_idl_table *table; /* The indexed table. */ -- struct ovsdb_idl_index_column *columns; /* The indexed columns. */ -- size_t n_columns; -- -- /* Skiplist with pointers to rows. */ -- struct skiplist *skiplist; -- -- /* True if a row in the index is being inserted or deleted. If true, the -- search key is augmented with the UUID and address to discriminate -- between entries with identical keys. */ -- bool ins_del; --}; -- --int ovsdb_idl_index_compare(struct ovsdb_idl_index *, -- const struct ovsdb_idl_row *a, -- const struct ovsdb_idl_row *b); -- --void ovsdb_idl_index_write(struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- struct ovsdb_datum *, -- const struct ovsdb_idl_table_class *); --struct ovsdb_idl_row *ovsdb_idl_index_init_row(struct ovsdb_idl_index *); --void ovsdb_idl_index_destroy_row(const struct ovsdb_idl_row *); -- --#ifdef __cplusplus --} --#endif -- --#endif /* ovsdb-idl-provider.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-idl-provider.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-idl-provider.h -@@ -0,0 +1,181 @@ -+/* Copyright (c) 2009, 2010, 2011, 2012, 2016 Nicira, Inc. -+ * Copyright (C) 2016 Hewlett Packard Enterprise Development LP -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_IDL_PROVIDER_H -+#define OVSDB_IDL_PROVIDER_H 1 -+ -+#include "openvswitch/hmap.h" -+#include "openvswitch/list.h" -+#include "openvswitch/ovsdb-idl.h" -+#include "openvswitch/ovsdb-map-op.h" -+#include "openvswitch/ovsdb-set-op.h" -+#include "openvswitch/ovsdb-types.h" -+#include "openvswitch/shash.h" -+#include "internal/sset.h" -+#include "internal/uuid.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* A local copy of a row in an OVSDB table, replicated from an OVSDB server. -+ * This structure is used as a header for a larger structure that translates -+ * the "struct ovsdb_datum"s into easier-to-use forms, via the ->parse() and -+ * ->unparse functions in struct ovsdb_idl_column. (Those functions are -+ * generated automatically via ovsdb-idlc.) -+ * -+ * When no transaction is in progress: -+ * -+ * - 'old_datum' points to the data committed to the database and currently -+ * in the row. -+ * -+ * - 'new_datum == old_datum'. -+ * -+ * When a transaction is in progress, the situation is a little different. For -+ * a row inserted in the transaction, 'old_datum' is NULL and 'new_datum' -+ * points to the row's initial contents. Otherwise: -+ * -+ * - 'old_datum' points to the data committed to the database and currently -+ * in the row. (This is the same as when no transaction is in progress.) -+ * -+ * - If the transaction does not modify the row, 'new_datum == old_datum'. -+ * -+ * - If the transaction modifies the row, 'new_datum' points to the -+ * modified data. -+ * -+ * - If the transaction deletes the row, 'new_datum' is NULL. -+ * -+ * Thus: -+ * -+ * - 'old_datum' always points to committed data, except that it is NULL if -+ * the row is inserted within the current transaction. -+ * -+ * - 'new_datum' always points to the newest, possibly uncommitted version -+ * of the row's data, except that it is NULL if the row is deleted within -+ * the current transaction. -+ */ -+struct ovsdb_idl_row { -+ struct hmap_node hmap_node; /* In struct ovsdb_idl_table's 'rows'. */ -+ struct uuid uuid; /* Row "_uuid" field. */ -+ struct ovs_list src_arcs; /* Forward arcs (ovsdb_idl_arc.src_node). */ -+ struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */ -+ struct ovsdb_idl_table *table; /* Containing table. */ -+ struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */ -+ bool parsed; /* Whether the row is parsed. */ -+ struct ovs_list reparse_node; /* Rows that needs to be re-parsed due to -+ * insertion of a referenced row. */ -+ -+ /* Transactional data. */ -+ struct ovsdb_datum *new_datum; /* Modified data (null to delete row). */ -+ unsigned long int *prereqs; /* Bitmap of "old_datum" columns to verify. */ -+ unsigned long int *written; /* Bitmap of "new_datum" columns to write. */ -+ struct hmap_node txn_node; /* Node in ovsdb_idl_txn's list. */ -+ unsigned long int *map_op_written; /* Bitmap of columns pending map ops. */ -+ struct map_op_list **map_op_lists; /* Per-column map operations. */ -+ unsigned long int *set_op_written; /* Bitmap of columns pending set ops. */ -+ struct set_op_list **set_op_lists; /* Per-column set operations. */ -+ -+ /* Tracking data */ -+ unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX]; -+ struct ovs_list track_node; /* Rows modified/added/deleted by IDL */ -+ unsigned long int *updated; /* Bitmap of columns updated by IDL */ -+ struct ovsdb_datum *tracked_old_datum; /* Old deleted data. */ -+}; -+ -+struct ovsdb_idl_column { -+ char *name; -+ struct ovsdb_type type; -+ bool is_mutable; -+ bool is_synthetic; -+ void (*parse)(struct ovsdb_idl_row *, const struct ovsdb_datum *); -+ void (*unparse)(struct ovsdb_idl_row *); -+}; -+ -+struct ovsdb_idl_table_class { -+ char *name; -+ bool is_root; -+ bool is_singleton; -+ const struct ovsdb_idl_column *columns; -+ size_t n_columns; -+ size_t allocation_size; -+ void (*row_init)(struct ovsdb_idl_row *); -+}; -+ -+struct ovsdb_idl_table { -+ const struct ovsdb_idl_table_class *class_; -+ unsigned char *modes; /* OVSDB_IDL_* bitmasks, indexed by column. */ -+ bool need_table; /* Monitor table even if no columns are selected -+ * for replication. */ -+ struct shash columns; /* Contains "const struct ovsdb_idl_column *"s. */ -+ struct sset schema_columns; /* Column names from schema. */ -+ struct hmap rows; /* Contains "struct ovsdb_idl_row"s. */ -+ struct ovsdb_idl *idl; /* Containing IDL instance. */ -+ unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX]; -+ bool in_server_schema; /* Indicates if this table is in the server schema -+ * or not. */ -+ struct ovs_list indexes; /* Contains "struct ovsdb_idl_index"s */ -+ struct ovs_list track_list; /* Tracked rows (ovsdb_idl_row.track_node). */ -+}; -+ -+struct ovsdb_idl_class { -+ const char *database; /* for this database. */ -+ const struct ovsdb_idl_table_class *tables; -+ size_t n_tables; -+}; -+ -+struct ovsdb_idl_row *ovsdb_idl_get_row_arc( -+ struct ovsdb_idl_row *src, -+ const struct ovsdb_idl_table_class *dst_table, -+ const struct uuid *dst_uuid); -+ -+void ovsdb_idl_txn_verify(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *); -+ -+struct ovsdb_idl_txn *ovsdb_idl_txn_get(const struct ovsdb_idl_row *); -+ -+/* Index internals. */ -+ -+struct ovsdb_idl_index { -+ struct ovs_list node; /* In ->table->indexes. */ -+ struct ovsdb_idl_table *table; /* The indexed table. */ -+ struct ovsdb_idl_index_column *columns; /* The indexed columns. */ -+ size_t n_columns; -+ -+ /* Skiplist with pointers to rows. */ -+ struct skiplist *skiplist; -+ -+ /* True if a row in the index is being inserted or deleted. If true, the -+ search key is augmented with the UUID and address to discriminate -+ between entries with identical keys. */ -+ bool ins_del; -+}; -+ -+int ovsdb_idl_index_compare(struct ovsdb_idl_index *, -+ const struct ovsdb_idl_row *a, -+ const struct ovsdb_idl_row *b); -+ -+void ovsdb_idl_index_write(struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ struct ovsdb_datum *, -+ const struct ovsdb_idl_table_class *); -+struct ovsdb_idl_row *ovsdb_idl_index_init_row(struct ovsdb_idl_index *); -+void ovsdb_idl_index_destroy_row(const struct ovsdb_idl_row *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* ovsdb-idl-provider.h */ -Index: openvswitch-2.17.2/lib/ovsdb-idl.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-idl.h -+++ /dev/null -@@ -1,488 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2019 Nicira, Inc. -- * Copyright (C) 2016 Hewlett Packard Enterprise Development LP -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_IDL_H --#define OVSDB_IDL_H 1 -- --/* Open vSwitch Database Interface Definition Language (OVSDB IDL). -- * -- * The OVSDB IDL maintains an in-memory replica of a database. It issues RPC -- * requests to an OVSDB database server and parses the responses, converting -- * raw JSON into data structures that are easier for clients to digest. Most -- * notably, references to rows via UUID become C pointers. -- * -- * The IDL always presents a consistent snapshot of the database to its client, -- * that is, it won't present the effects of some part of a transaction applied -- * at the database server without presenting all of its effects. -- * -- * The IDL also assists with issuing database transactions. The client creates -- * a transaction, manipulates the IDL data structures, and commits or aborts -- * the transaction. The IDL then composes and issues the necessary JSON-RPC -- * requests and reports to the client whether the transaction completed -- * successfully. -- */ -- --#include --#include --#include "openvswitch/compiler.h" --#include "ovsdb-types.h" --#include "ovsdb-data.h" --#include "openvswitch/list.h" --#include "ovsdb-condition.h" --#include "skiplist.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --struct json; --struct ovsdb_datum; --struct ovsdb_idl_class; --struct ovsdb_idl_row; --struct ovsdb_idl_column; --struct ovsdb_idl_table; --struct ovsdb_idl_table_class; --struct simap; --struct uuid; -- --struct ovsdb_idl *ovsdb_idl_create(const char *remote, -- const struct ovsdb_idl_class *, -- bool monitor_everything_by_default, -- bool retry); --struct ovsdb_idl *ovsdb_idl_create_unconnected( -- const struct ovsdb_idl_class *, bool monitor_everything_by_default); --void ovsdb_idl_set_remote(struct ovsdb_idl *, const char *remote, bool retry); --void ovsdb_idl_set_shuffle_remotes(struct ovsdb_idl *, bool shuffle); --void ovsdb_idl_reset_min_index(struct ovsdb_idl *); --void ovsdb_idl_destroy(struct ovsdb_idl *); -- --void ovsdb_idl_set_leader_only(struct ovsdb_idl *, bool leader_only); -- --void ovsdb_idl_run(struct ovsdb_idl *); --void ovsdb_idl_wait(struct ovsdb_idl *); -- --void ovsdb_idl_get_memory_usage(struct ovsdb_idl *, struct simap *usage); -- --void ovsdb_idl_set_lock(struct ovsdb_idl *, const char *lock_name); --bool ovsdb_idl_has_lock(const struct ovsdb_idl *); --bool ovsdb_idl_is_lock_contended(const struct ovsdb_idl *); -- --unsigned int ovsdb_idl_get_seqno(const struct ovsdb_idl *); --bool ovsdb_idl_has_ever_connected(const struct ovsdb_idl *); --void ovsdb_idl_enable_reconnect(struct ovsdb_idl *); --void ovsdb_idl_force_reconnect(struct ovsdb_idl *); --void ovsdb_idl_verify_write_only(struct ovsdb_idl *); -- --bool ovsdb_idl_is_alive(const struct ovsdb_idl *); --bool ovsdb_idl_is_connected(const struct ovsdb_idl *idl); --int ovsdb_idl_get_last_error(const struct ovsdb_idl *); -- --void ovsdb_idl_set_probe_interval(const struct ovsdb_idl *, int probe_interval); -- --void ovsdb_idl_check_consistency(const struct ovsdb_idl *); -- --const struct ovsdb_idl_class *ovsdb_idl_get_class(const struct ovsdb_idl *); --const struct ovsdb_idl_table_class *ovsdb_idl_table_class_from_column( -- const struct ovsdb_idl_class *, const struct ovsdb_idl_column *); --bool ovsdb_idl_server_has_table(const struct ovsdb_idl *, -- const struct ovsdb_idl_table_class *); --bool ovsdb_idl_server_has_column(const struct ovsdb_idl *, -- const struct ovsdb_idl_column *); -- --/* Choosing columns and tables to replicate. -- * -- * The client may choose any subset of the columns and tables to replicate, -- * specifying it one of two ways: -- * -- * - As a deny list (adding the columns or tables to replicate). To do so, -- * the client passes false as 'monitor_everything_by_default' to -- * ovsdb_idl_create() and then calls ovsdb_idl_add_column() and -- * ovsdb_idl_add_table() for the desired columns and, if necessary, tables. -- * -- * - As an allow list (replicating all columns and tables except those -- * explicitly removed). To do so, the client passes true as -- * 'monitor_everything_by_default' to ovsdb_idl_create() and then calls -- * ovsdb_idl_omit() to remove columns. -- * -- * There are multiple modes a column may be replicated: -- * -- * - Read-only. This is the default. Whenever the column changes in any -- * replicated row, the value returned by ovsdb_idl_get_seqno() will change, -- * letting the client know to look at the replicated data again. -- * -- * - Write-only. This is for columns that the client sets and updates but -- * does not want to be alerted about its own updates (which, at the OVSDB -- * level, cannot be distinguished from updates made by any other client). -- * The column will be replicated in the same way as for read-only columns, -- * but the value returned by ovsdb_idl_get_seqno() will not change when the -- * column changes, saving wasted CPU time. -- * -- * (A "write-only" client probably does read the column so that it can know -- * whether it needs to update it, but it doesn't expect to react to changes -- * by other clients.) -- * -- * To mark a replicated column as write-only, a client calls -- * ovsdb_idl_omit_alert(). (The column must already be replicated one of -- * the ways described in the previous list.) -- * -- * This is an optimization only and does not affect behavioral correctness -- * of an otherwise well-written client. -- * -- * - Read/write. In theory, an OVSDB client might both read and write a -- * column, although OVSDB schemas are usually designed so that any given -- * client only does one or the other. This is actually the same as -- * read/write columns; that is, the client need take no special action. -- */ -- --/* Modes with which the IDL can replicate a column. See above comment for -- * overview. -- * -- * If no bits are set, the IDL does not replicate the column at all. The -- * client will always see it with the default value for its type. -- * -- * If OVSDB_IDL_MONITOR is set, then the IDL replicates the column and sets it -- * to to the value in the database. If OVSDB_IDL_ALERT is also set, then the -- * IDL will change the value returned by ovsdb_idl_get_seqno() when the -- * column's value changes in any row. -- * -- * The possible mode combinations are: -- * -- * - 0, for a column that a client doesn't care about. This is the default -- * for every column in every table, if the client passes false for -- * 'monitor_everything_by_default' to ovsdb_idl_create(). -- * -- * - (OVSDB_IDL_MONITOR | OVSDB_IDL_ALERT), for a column that a client wants -- * to track and possibly update. This is the default for every column in -- * every table, if the client passes true for -- * 'monitor_everything_by_default' to ovsdb_idl_create(). -- * -- * - OVSDB_IDL_MONITOR, for columns that a client treats as "write-only", -- * that is, it updates them but doesn't want to get alerted about its own -- * updates. It also won't be alerted about other clients' updates, so this -- * is suitable only for use by a client that "owns" a particular column. -- * Use ovsdb_idl_omit_alert() to set a column that is already replicated to -- * this mode. -- * -- * - OVDSB_IDL_ALERT without OVSDB_IDL_MONITOR is not valid. -- * -- * - (OVSDB_IDL_MONITOR | OVSDB_IDL_ALERT | OVSDB_IDL_TRACK), for a column -- * that a client wants to track using the change tracking -- * ovsdb_idl_track_get_*() functions. -- */ --#define OVSDB_IDL_MONITOR (1 << 0) /* Replicate this column? */ --#define OVSDB_IDL_ALERT (1 << 1) /* Alert client when column changes? */ --#define OVSDB_IDL_TRACK (1 << 2) -- --void ovsdb_idl_add_column(struct ovsdb_idl *, const struct ovsdb_idl_column *); --void ovsdb_idl_add_table(struct ovsdb_idl *, -- const struct ovsdb_idl_table_class *); -- --void ovsdb_idl_omit(struct ovsdb_idl *, const struct ovsdb_idl_column *); --void ovsdb_idl_omit_alert(struct ovsdb_idl *, const struct ovsdb_idl_column *); -- --/* Change tracking. -- * -- * In OVSDB, change tracking is applied at each client in the IDL layer. This -- * means that when a client makes a request to track changes on a particular -- * table, they are essentially requesting information about the incremental -- * changes to that table from the point in time that the request is made. Once -- * the client clears tracked changes, that information will no longer be -- * available. -- * -- * The implication of the above is that if a client requires replaying -- * untracked history, it faces the choice of either trying to remember changes -- * itself (which translates into a memory leak) or of being structured with a -- * path for processing the full untracked table as well as a path that -- * processes incremental changes. */ --enum ovsdb_idl_change { -- OVSDB_IDL_CHANGE_INSERT, -- OVSDB_IDL_CHANGE_MODIFY, -- OVSDB_IDL_CHANGE_DELETE, -- OVSDB_IDL_CHANGE_MAX --}; -- --/* Row, table sequence numbers */ --unsigned int ovsdb_idl_table_get_seqno( -- const struct ovsdb_idl *idl, -- const struct ovsdb_idl_table_class *table_class); --unsigned int ovsdb_idl_row_get_seqno( -- const struct ovsdb_idl_row *row, -- enum ovsdb_idl_change change); -- --void ovsdb_idl_track_add_column(struct ovsdb_idl *idl, -- const struct ovsdb_idl_column *column); --void ovsdb_idl_track_add_all(struct ovsdb_idl *idl); --bool ovsdb_idl_track_is_set(struct ovsdb_idl_table *table); --const struct ovsdb_idl_row *ovsdb_idl_track_get_first( -- const struct ovsdb_idl *, const struct ovsdb_idl_table_class *); --const struct ovsdb_idl_row *ovsdb_idl_track_get_next(const struct ovsdb_idl_row *); --bool ovsdb_idl_track_is_updated(const struct ovsdb_idl_row *row, -- const struct ovsdb_idl_column *column); --void ovsdb_idl_track_clear(struct ovsdb_idl *); -- -- --/* Reading the database replica. */ -- --const struct ovsdb_idl_row *ovsdb_idl_get_row_for_uuid( -- const struct ovsdb_idl *, const struct ovsdb_idl_table_class *, -- const struct uuid *); --const struct ovsdb_idl_row *ovsdb_idl_first_row( -- const struct ovsdb_idl *, const struct ovsdb_idl_table_class *); --const struct ovsdb_idl_row *ovsdb_idl_next_row(const struct ovsdb_idl_row *); -- --const struct ovsdb_datum *ovsdb_idl_read(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *); --const struct ovsdb_datum *ovsdb_idl_get(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- enum ovsdb_atomic_type key_type, -- enum ovsdb_atomic_type value_type); --bool ovsdb_idl_is_mutable(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *); -- --bool ovsdb_idl_row_is_synthetic(const struct ovsdb_idl_row *); -- --/* Transactions. -- * -- * A transaction may modify the contents of a database by modifying the values -- * of columns, deleting rows, inserting rows, or adding checks that columns in -- * the database have not changed ("verify" operations), through -- * ovsdb_idl_txn_*() functions. (The OVSDB IDL code generator produces helper -- * functions that internally call the ovsdb_idl_txn_*() functions. These are -- * likely to be more convenient.) -- * -- * Reading and writing columns and inserting and deleting rows are all -- * straightforward. The reasons to verify columns are less obvious. -- * Verification is the key to maintaining transactional integrity. Because -- * OVSDB handles multiple clients, it can happen that between the time that -- * OVSDB client A reads a column and writes a new value, OVSDB client B has -- * written that column. Client A's write should not ordinarily overwrite -- * client B's, especially if the column in question is a "map" column that -- * contains several more or less independent data items. If client A adds a -- * "verify" operation before it writes the column, then the transaction fails -- * in case client B modifies it first. Client A will then see the new value of -- * the column and compose a new transaction based on the new contents written -- * by client B. -- * -- * When a transaction is complete, which must be before the next call to -- * ovsdb_idl_run() on 'idl', call ovsdb_idl_txn_commit() or -- * ovsdb_idl_txn_abort(). -- * -- * The life-cycle of a transaction looks like this: -- * -- * 1. Create the transaction and record the initial sequence number: -- * -- * seqno = ovsdb_idl_get_seqno(idl); -- * txn = ovsdb_idl_txn_create(idl); -- * -- * 2. Modify the database with ovsdb_idl_txn_*() functions directly or -- * indirectly. -- * -- * 3. Commit the transaction by calling ovsdb_idl_txn_commit(). The first call -- * to this function probably returns TXN_INCOMPLETE. The client must keep -- * calling again along as this remains true, calling ovsdb_idl_run() in -- * between to let the IDL do protocol processing. (If the client doesn't -- * have anything else to do in the meantime, it can use -- * ovsdb_idl_txn_commit_block() to avoid having to loop itself.) -- * -- * 4. If the final status is TXN_TRY_AGAIN, wait for ovsdb_idl_get_seqno() to -- * change from the saved 'seqno' (it's possible that it's already changed, -- * in which case the client should not wait at all), then start over from -- * step 1. Only a call to ovsdb_idl_run() will change the return value of -- * ovsdb_idl_get_seqno(). (ovsdb_idl_txn_commit_block() calls -- * ovsdb_idl_run().) -- */ -- --enum ovsdb_idl_txn_status { -- TXN_UNCOMMITTED, /* Not yet committed or aborted. */ -- TXN_UNCHANGED, /* Transaction didn't include any changes. */ -- TXN_INCOMPLETE, /* Commit in progress, please wait. */ -- TXN_ABORTED, /* ovsdb_idl_txn_abort() called. */ -- TXN_SUCCESS, /* Commit successful. */ -- TXN_TRY_AGAIN, /* Commit failed because a "verify" operation -- * reported an inconsistency, due to a network -- * problem, or other transient failure. Wait -- * for a change, then try again. */ -- TXN_NOT_LOCKED, /* Server hasn't given us the lock yet. */ -- TXN_ERROR /* Commit failed due to a hard error. */ --}; -- --const char *ovsdb_idl_txn_status_to_string(enum ovsdb_idl_txn_status); -- --struct ovsdb_idl_txn *ovsdb_idl_txn_create(struct ovsdb_idl *); --void ovsdb_idl_txn_add_comment(struct ovsdb_idl_txn *, const char *, ...) -- OVS_PRINTF_FORMAT (2, 3); --void ovsdb_idl_txn_set_dry_run(struct ovsdb_idl_txn *); --void ovsdb_idl_txn_increment(struct ovsdb_idl_txn *, -- const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- bool force); --void ovsdb_idl_txn_destroy(struct ovsdb_idl_txn *); --void ovsdb_idl_txn_wait(const struct ovsdb_idl_txn *); --enum ovsdb_idl_txn_status ovsdb_idl_txn_commit(struct ovsdb_idl_txn *); --enum ovsdb_idl_txn_status ovsdb_idl_txn_commit_block(struct ovsdb_idl_txn *); --void ovsdb_idl_txn_abort(struct ovsdb_idl_txn *); -- --const char *ovsdb_idl_txn_get_error(const struct ovsdb_idl_txn *); -- --int64_t ovsdb_idl_txn_get_increment_new_value(const struct ovsdb_idl_txn *); --const struct uuid *ovsdb_idl_txn_get_insert_uuid(const struct ovsdb_idl_txn *, -- const struct uuid *); -- --void ovsdb_idl_txn_write(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- struct ovsdb_datum *); --void ovsdb_idl_txn_write_clone(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- const struct ovsdb_datum *); --void ovsdb_idl_txn_write_partial_map(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- struct ovsdb_datum *); --void ovsdb_idl_txn_delete_partial_map(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- struct ovsdb_datum *); --void ovsdb_idl_txn_write_partial_set(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- struct ovsdb_datum *); --void ovsdb_idl_txn_delete_partial_set(const struct ovsdb_idl_row *, -- const struct ovsdb_idl_column *, -- struct ovsdb_datum *); --void ovsdb_idl_txn_delete(const struct ovsdb_idl_row *); --const struct ovsdb_idl_row *ovsdb_idl_txn_insert( -- struct ovsdb_idl_txn *, const struct ovsdb_idl_table_class *, -- const struct uuid *); -- --struct ovsdb_idl *ovsdb_idl_txn_get_idl (struct ovsdb_idl_txn *); --void ovsdb_idl_get_initial_snapshot(struct ovsdb_idl *); -- -- --/* ovsdb_idl_loop provides an easy way to manage the transactions related -- * to 'idl' and to cope with different status during transaction. */ --struct ovsdb_idl_loop { -- struct ovsdb_idl *idl; -- unsigned int skip_seqno; -- -- struct ovsdb_idl_txn *committing_txn; -- unsigned int precommit_seqno; -- -- struct ovsdb_idl_txn *open_txn; -- -- /* These members allow a client a simple, stateless way to keep track of -- * transactions that commit: when a transaction commits successfully, -- * ovsdb_idl_loop_commit_and_wait() copies 'next_cfg' to 'cur_cfg'. Thus, -- * the client can set 'next_cfg' to a value that indicates a successful -- * commit and check 'cur_cfg' on each iteration. */ -- int64_t cur_cfg; -- int64_t next_cfg; --}; -- --#define OVSDB_IDL_LOOP_INITIALIZER(IDL) { .idl = (IDL) } -- --void ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *); --struct ovsdb_idl_txn *ovsdb_idl_loop_run(struct ovsdb_idl_loop *); --int ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *); -- --/* Conditional Replication -- * ======================= -- * -- * By default, when the IDL replicates a particular table in the database, it -- * replicates every row in the table. These functions allow the client to -- * specify that only selected rows should be replicated, by constructing a -- * per-table condition that specifies the rows to replicate. -- * -- * A condition is a disjunction of clauses. The condition is true, and thus a -- * row is replicated, if any of the clauses evaluates to true for a given row. -- * (Thus, a condition with no clauses is always false.) -- */ -- --struct ovsdb_idl_condition { -- struct hmap clauses; /* Contains "struct ovsdb_idl_clause"s. */ -- bool is_true; /* Is the condition unconditionally true? */ --}; --#define OVSDB_IDL_CONDITION_INIT(CONDITION) \ -- { HMAP_INITIALIZER(&(CONDITION)->clauses), false } -- --void ovsdb_idl_condition_init(struct ovsdb_idl_condition *); --void ovsdb_idl_condition_clear(struct ovsdb_idl_condition *); --void ovsdb_idl_condition_destroy(struct ovsdb_idl_condition *); --void ovsdb_idl_condition_add_clause(struct ovsdb_idl_condition *, -- enum ovsdb_function function, -- const struct ovsdb_idl_column *column, -- const struct ovsdb_datum *arg); --void ovsdb_idl_condition_add_clause_true(struct ovsdb_idl_condition *); --bool ovsdb_idl_condition_is_true(const struct ovsdb_idl_condition *); -- --unsigned int ovsdb_idl_set_condition(struct ovsdb_idl *, -- const struct ovsdb_idl_table_class *, -- const struct ovsdb_idl_condition *); -- --unsigned int ovsdb_idl_get_condition_seqno(const struct ovsdb_idl *); -- --/* Indexes over one or more columns in the IDL, to retrieve rows matching -- * particular search criteria and to iterate over a subset of rows in a defined -- * order. */ -- --enum ovsdb_index_order { -- OVSDB_INDEX_ASC, /* 0, 1, 2, ... */ -- OVSDB_INDEX_DESC /* 2, 1, 0, ... */ --}; -- --typedef int column_comparator_func(const void *a, const void *b); -- --struct ovsdb_idl_index_column { -- const struct ovsdb_idl_column *column; -- column_comparator_func *comparer; -- enum ovsdb_index_order order; --}; -- --/* Creating an index. */ --struct ovsdb_idl_index *ovsdb_idl_index_create( -- struct ovsdb_idl *, const struct ovsdb_idl_index_column *, size_t n); --struct ovsdb_idl_index *ovsdb_idl_index_create1( -- struct ovsdb_idl *, const struct ovsdb_idl_column *); --struct ovsdb_idl_index *ovsdb_idl_index_create2( -- struct ovsdb_idl *, const struct ovsdb_idl_column *, -- const struct ovsdb_idl_column *); -- --/* Searching an index. */ --struct ovsdb_idl_row *ovsdb_idl_index_find(struct ovsdb_idl_index *, -- const struct ovsdb_idl_row *); -- --/* Iteration over an index. -- * -- * Usually these would be invoked through table-specific wrappers generated -- * by the IDL. */ -- --struct ovsdb_idl_cursor { -- struct ovsdb_idl_index *index; /* Index being iterated. */ -- struct skiplist_node *position; /* Current position in 'index'. */ --}; -- --struct ovsdb_idl_cursor ovsdb_idl_cursor_first(struct ovsdb_idl_index *); --struct ovsdb_idl_cursor ovsdb_idl_cursor_first_eq( -- struct ovsdb_idl_index *, const struct ovsdb_idl_row *); --struct ovsdb_idl_cursor ovsdb_idl_cursor_first_ge( -- struct ovsdb_idl_index *, const struct ovsdb_idl_row *); -- --void ovsdb_idl_cursor_next(struct ovsdb_idl_cursor *); --void ovsdb_idl_cursor_next_eq(struct ovsdb_idl_cursor *); -- --struct ovsdb_idl_row *ovsdb_idl_cursor_data(struct ovsdb_idl_cursor *); -- --#ifdef __cplusplus --} --#endif -- --#endif /* ovsdb-idl.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-idl.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-idl.h -@@ -0,0 +1,488 @@ -+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2019 Nicira, Inc. -+ * Copyright (C) 2016 Hewlett Packard Enterprise Development LP -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_IDL_H -+#define OVSDB_IDL_H 1 -+ -+/* Open vSwitch Database Interface Definition Language (OVSDB IDL). -+ * -+ * The OVSDB IDL maintains an in-memory replica of a database. It issues RPC -+ * requests to an OVSDB database server and parses the responses, converting -+ * raw JSON into data structures that are easier for clients to digest. Most -+ * notably, references to rows via UUID become C pointers. -+ * -+ * The IDL always presents a consistent snapshot of the database to its client, -+ * that is, it won't present the effects of some part of a transaction applied -+ * at the database server without presenting all of its effects. -+ * -+ * The IDL also assists with issuing database transactions. The client creates -+ * a transaction, manipulates the IDL data structures, and commits or aborts -+ * the transaction. The IDL then composes and issues the necessary JSON-RPC -+ * requests and reports to the client whether the transaction completed -+ * successfully. -+ */ -+ -+#include -+#include -+#include "openvswitch/compiler.h" -+#include "openvswitch/ovsdb-types.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/list.h" -+#include "openvswitch/ovsdb-condition.h" -+#include "internal/skiplist.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct json; -+struct ovsdb_datum; -+struct ovsdb_idl_class; -+struct ovsdb_idl_row; -+struct ovsdb_idl_column; -+struct ovsdb_idl_table; -+struct ovsdb_idl_table_class; -+struct simap; -+struct uuid; -+ -+struct ovsdb_idl *ovsdb_idl_create(const char *remote, -+ const struct ovsdb_idl_class *, -+ bool monitor_everything_by_default, -+ bool retry); -+struct ovsdb_idl *ovsdb_idl_create_unconnected( -+ const struct ovsdb_idl_class *, bool monitor_everything_by_default); -+void ovsdb_idl_set_remote(struct ovsdb_idl *, const char *remote, bool retry); -+void ovsdb_idl_set_shuffle_remotes(struct ovsdb_idl *, bool shuffle); -+void ovsdb_idl_reset_min_index(struct ovsdb_idl *); -+void ovsdb_idl_destroy(struct ovsdb_idl *); -+ -+void ovsdb_idl_set_leader_only(struct ovsdb_idl *, bool leader_only); -+ -+void ovsdb_idl_run(struct ovsdb_idl *); -+void ovsdb_idl_wait(struct ovsdb_idl *); -+ -+void ovsdb_idl_get_memory_usage(struct ovsdb_idl *, struct simap *usage); -+ -+void ovsdb_idl_set_lock(struct ovsdb_idl *, const char *lock_name); -+bool ovsdb_idl_has_lock(const struct ovsdb_idl *); -+bool ovsdb_idl_is_lock_contended(const struct ovsdb_idl *); -+ -+unsigned int ovsdb_idl_get_seqno(const struct ovsdb_idl *); -+bool ovsdb_idl_has_ever_connected(const struct ovsdb_idl *); -+void ovsdb_idl_enable_reconnect(struct ovsdb_idl *); -+void ovsdb_idl_force_reconnect(struct ovsdb_idl *); -+void ovsdb_idl_verify_write_only(struct ovsdb_idl *); -+ -+bool ovsdb_idl_is_alive(const struct ovsdb_idl *); -+bool ovsdb_idl_is_connected(const struct ovsdb_idl *idl); -+int ovsdb_idl_get_last_error(const struct ovsdb_idl *); -+ -+void ovsdb_idl_set_probe_interval(const struct ovsdb_idl *, int probe_interval); -+ -+void ovsdb_idl_check_consistency(const struct ovsdb_idl *); -+ -+const struct ovsdb_idl_class *ovsdb_idl_get_class(const struct ovsdb_idl *); -+const struct ovsdb_idl_table_class *ovsdb_idl_table_class_from_column( -+ const struct ovsdb_idl_class *, const struct ovsdb_idl_column *); -+bool ovsdb_idl_server_has_table(const struct ovsdb_idl *, -+ const struct ovsdb_idl_table_class *); -+bool ovsdb_idl_server_has_column(const struct ovsdb_idl *, -+ const struct ovsdb_idl_column *); -+ -+/* Choosing columns and tables to replicate. -+ * -+ * The client may choose any subset of the columns and tables to replicate, -+ * specifying it one of two ways: -+ * -+ * - As a deny list (adding the columns or tables to replicate). To do so, -+ * the client passes false as 'monitor_everything_by_default' to -+ * ovsdb_idl_create() and then calls ovsdb_idl_add_column() and -+ * ovsdb_idl_add_table() for the desired columns and, if necessary, tables. -+ * -+ * - As an allow list (replicating all columns and tables except those -+ * explicitly removed). To do so, the client passes true as -+ * 'monitor_everything_by_default' to ovsdb_idl_create() and then calls -+ * ovsdb_idl_omit() to remove columns. -+ * -+ * There are multiple modes a column may be replicated: -+ * -+ * - Read-only. This is the default. Whenever the column changes in any -+ * replicated row, the value returned by ovsdb_idl_get_seqno() will change, -+ * letting the client know to look at the replicated data again. -+ * -+ * - Write-only. This is for columns that the client sets and updates but -+ * does not want to be alerted about its own updates (which, at the OVSDB -+ * level, cannot be distinguished from updates made by any other client). -+ * The column will be replicated in the same way as for read-only columns, -+ * but the value returned by ovsdb_idl_get_seqno() will not change when the -+ * column changes, saving wasted CPU time. -+ * -+ * (A "write-only" client probably does read the column so that it can know -+ * whether it needs to update it, but it doesn't expect to react to changes -+ * by other clients.) -+ * -+ * To mark a replicated column as write-only, a client calls -+ * ovsdb_idl_omit_alert(). (The column must already be replicated one of -+ * the ways described in the previous list.) -+ * -+ * This is an optimization only and does not affect behavioral correctness -+ * of an otherwise well-written client. -+ * -+ * - Read/write. In theory, an OVSDB client might both read and write a -+ * column, although OVSDB schemas are usually designed so that any given -+ * client only does one or the other. This is actually the same as -+ * read/write columns; that is, the client need take no special action. -+ */ -+ -+/* Modes with which the IDL can replicate a column. See above comment for -+ * overview. -+ * -+ * If no bits are set, the IDL does not replicate the column at all. The -+ * client will always see it with the default value for its type. -+ * -+ * If OVSDB_IDL_MONITOR is set, then the IDL replicates the column and sets it -+ * to to the value in the database. If OVSDB_IDL_ALERT is also set, then the -+ * IDL will change the value returned by ovsdb_idl_get_seqno() when the -+ * column's value changes in any row. -+ * -+ * The possible mode combinations are: -+ * -+ * - 0, for a column that a client doesn't care about. This is the default -+ * for every column in every table, if the client passes false for -+ * 'monitor_everything_by_default' to ovsdb_idl_create(). -+ * -+ * - (OVSDB_IDL_MONITOR | OVSDB_IDL_ALERT), for a column that a client wants -+ * to track and possibly update. This is the default for every column in -+ * every table, if the client passes true for -+ * 'monitor_everything_by_default' to ovsdb_idl_create(). -+ * -+ * - OVSDB_IDL_MONITOR, for columns that a client treats as "write-only", -+ * that is, it updates them but doesn't want to get alerted about its own -+ * updates. It also won't be alerted about other clients' updates, so this -+ * is suitable only for use by a client that "owns" a particular column. -+ * Use ovsdb_idl_omit_alert() to set a column that is already replicated to -+ * this mode. -+ * -+ * - OVDSB_IDL_ALERT without OVSDB_IDL_MONITOR is not valid. -+ * -+ * - (OVSDB_IDL_MONITOR | OVSDB_IDL_ALERT | OVSDB_IDL_TRACK), for a column -+ * that a client wants to track using the change tracking -+ * ovsdb_idl_track_get_*() functions. -+ */ -+#define OVSDB_IDL_MONITOR (1 << 0) /* Replicate this column? */ -+#define OVSDB_IDL_ALERT (1 << 1) /* Alert client when column changes? */ -+#define OVSDB_IDL_TRACK (1 << 2) -+ -+void ovsdb_idl_add_column(struct ovsdb_idl *, const struct ovsdb_idl_column *); -+void ovsdb_idl_add_table(struct ovsdb_idl *, -+ const struct ovsdb_idl_table_class *); -+ -+void ovsdb_idl_omit(struct ovsdb_idl *, const struct ovsdb_idl_column *); -+void ovsdb_idl_omit_alert(struct ovsdb_idl *, const struct ovsdb_idl_column *); -+ -+/* Change tracking. -+ * -+ * In OVSDB, change tracking is applied at each client in the IDL layer. This -+ * means that when a client makes a request to track changes on a particular -+ * table, they are essentially requesting information about the incremental -+ * changes to that table from the point in time that the request is made. Once -+ * the client clears tracked changes, that information will no longer be -+ * available. -+ * -+ * The implication of the above is that if a client requires replaying -+ * untracked history, it faces the choice of either trying to remember changes -+ * itself (which translates into a memory leak) or of being structured with a -+ * path for processing the full untracked table as well as a path that -+ * processes incremental changes. */ -+enum ovsdb_idl_change { -+ OVSDB_IDL_CHANGE_INSERT, -+ OVSDB_IDL_CHANGE_MODIFY, -+ OVSDB_IDL_CHANGE_DELETE, -+ OVSDB_IDL_CHANGE_MAX -+}; -+ -+/* Row, table sequence numbers */ -+unsigned int ovsdb_idl_table_get_seqno( -+ const struct ovsdb_idl *idl, -+ const struct ovsdb_idl_table_class *table_class); -+unsigned int ovsdb_idl_row_get_seqno( -+ const struct ovsdb_idl_row *row, -+ enum ovsdb_idl_change change); -+ -+void ovsdb_idl_track_add_column(struct ovsdb_idl *idl, -+ const struct ovsdb_idl_column *column); -+void ovsdb_idl_track_add_all(struct ovsdb_idl *idl); -+bool ovsdb_idl_track_is_set(struct ovsdb_idl_table *table); -+const struct ovsdb_idl_row *ovsdb_idl_track_get_first( -+ const struct ovsdb_idl *, const struct ovsdb_idl_table_class *); -+const struct ovsdb_idl_row *ovsdb_idl_track_get_next(const struct ovsdb_idl_row *); -+bool ovsdb_idl_track_is_updated(const struct ovsdb_idl_row *row, -+ const struct ovsdb_idl_column *column); -+void ovsdb_idl_track_clear(struct ovsdb_idl *); -+ -+ -+/* Reading the database replica. */ -+ -+const struct ovsdb_idl_row *ovsdb_idl_get_row_for_uuid( -+ const struct ovsdb_idl *, const struct ovsdb_idl_table_class *, -+ const struct uuid *); -+const struct ovsdb_idl_row *ovsdb_idl_first_row( -+ const struct ovsdb_idl *, const struct ovsdb_idl_table_class *); -+const struct ovsdb_idl_row *ovsdb_idl_next_row(const struct ovsdb_idl_row *); -+ -+const struct ovsdb_datum *ovsdb_idl_read(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *); -+const struct ovsdb_datum *ovsdb_idl_get(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ enum ovsdb_atomic_type key_type, -+ enum ovsdb_atomic_type value_type); -+bool ovsdb_idl_is_mutable(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *); -+ -+bool ovsdb_idl_row_is_synthetic(const struct ovsdb_idl_row *); -+ -+/* Transactions. -+ * -+ * A transaction may modify the contents of a database by modifying the values -+ * of columns, deleting rows, inserting rows, or adding checks that columns in -+ * the database have not changed ("verify" operations), through -+ * ovsdb_idl_txn_*() functions. (The OVSDB IDL code generator produces helper -+ * functions that internally call the ovsdb_idl_txn_*() functions. These are -+ * likely to be more convenient.) -+ * -+ * Reading and writing columns and inserting and deleting rows are all -+ * straightforward. The reasons to verify columns are less obvious. -+ * Verification is the key to maintaining transactional integrity. Because -+ * OVSDB handles multiple clients, it can happen that between the time that -+ * OVSDB client A reads a column and writes a new value, OVSDB client B has -+ * written that column. Client A's write should not ordinarily overwrite -+ * client B's, especially if the column in question is a "map" column that -+ * contains several more or less independent data items. If client A adds a -+ * "verify" operation before it writes the column, then the transaction fails -+ * in case client B modifies it first. Client A will then see the new value of -+ * the column and compose a new transaction based on the new contents written -+ * by client B. -+ * -+ * When a transaction is complete, which must be before the next call to -+ * ovsdb_idl_run() on 'idl', call ovsdb_idl_txn_commit() or -+ * ovsdb_idl_txn_abort(). -+ * -+ * The life-cycle of a transaction looks like this: -+ * -+ * 1. Create the transaction and record the initial sequence number: -+ * -+ * seqno = ovsdb_idl_get_seqno(idl); -+ * txn = ovsdb_idl_txn_create(idl); -+ * -+ * 2. Modify the database with ovsdb_idl_txn_*() functions directly or -+ * indirectly. -+ * -+ * 3. Commit the transaction by calling ovsdb_idl_txn_commit(). The first call -+ * to this function probably returns TXN_INCOMPLETE. The client must keep -+ * calling again along as this remains true, calling ovsdb_idl_run() in -+ * between to let the IDL do protocol processing. (If the client doesn't -+ * have anything else to do in the meantime, it can use -+ * ovsdb_idl_txn_commit_block() to avoid having to loop itself.) -+ * -+ * 4. If the final status is TXN_TRY_AGAIN, wait for ovsdb_idl_get_seqno() to -+ * change from the saved 'seqno' (it's possible that it's already changed, -+ * in which case the client should not wait at all), then start over from -+ * step 1. Only a call to ovsdb_idl_run() will change the return value of -+ * ovsdb_idl_get_seqno(). (ovsdb_idl_txn_commit_block() calls -+ * ovsdb_idl_run().) -+ */ -+ -+enum ovsdb_idl_txn_status { -+ TXN_UNCOMMITTED, /* Not yet committed or aborted. */ -+ TXN_UNCHANGED, /* Transaction didn't include any changes. */ -+ TXN_INCOMPLETE, /* Commit in progress, please wait. */ -+ TXN_ABORTED, /* ovsdb_idl_txn_abort() called. */ -+ TXN_SUCCESS, /* Commit successful. */ -+ TXN_TRY_AGAIN, /* Commit failed because a "verify" operation -+ * reported an inconsistency, due to a network -+ * problem, or other transient failure. Wait -+ * for a change, then try again. */ -+ TXN_NOT_LOCKED, /* Server hasn't given us the lock yet. */ -+ TXN_ERROR /* Commit failed due to a hard error. */ -+}; -+ -+const char *ovsdb_idl_txn_status_to_string(enum ovsdb_idl_txn_status); -+ -+struct ovsdb_idl_txn *ovsdb_idl_txn_create(struct ovsdb_idl *); -+void ovsdb_idl_txn_add_comment(struct ovsdb_idl_txn *, const char *, ...) -+ OVS_PRINTF_FORMAT (2, 3); -+void ovsdb_idl_txn_set_dry_run(struct ovsdb_idl_txn *); -+void ovsdb_idl_txn_increment(struct ovsdb_idl_txn *, -+ const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ bool force); -+void ovsdb_idl_txn_destroy(struct ovsdb_idl_txn *); -+void ovsdb_idl_txn_wait(const struct ovsdb_idl_txn *); -+enum ovsdb_idl_txn_status ovsdb_idl_txn_commit(struct ovsdb_idl_txn *); -+enum ovsdb_idl_txn_status ovsdb_idl_txn_commit_block(struct ovsdb_idl_txn *); -+void ovsdb_idl_txn_abort(struct ovsdb_idl_txn *); -+ -+const char *ovsdb_idl_txn_get_error(const struct ovsdb_idl_txn *); -+ -+int64_t ovsdb_idl_txn_get_increment_new_value(const struct ovsdb_idl_txn *); -+const struct uuid *ovsdb_idl_txn_get_insert_uuid(const struct ovsdb_idl_txn *, -+ const struct uuid *); -+ -+void ovsdb_idl_txn_write(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ struct ovsdb_datum *); -+void ovsdb_idl_txn_write_clone(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ const struct ovsdb_datum *); -+void ovsdb_idl_txn_write_partial_map(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ struct ovsdb_datum *); -+void ovsdb_idl_txn_delete_partial_map(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ struct ovsdb_datum *); -+void ovsdb_idl_txn_write_partial_set(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ struct ovsdb_datum *); -+void ovsdb_idl_txn_delete_partial_set(const struct ovsdb_idl_row *, -+ const struct ovsdb_idl_column *, -+ struct ovsdb_datum *); -+void ovsdb_idl_txn_delete(const struct ovsdb_idl_row *); -+const struct ovsdb_idl_row *ovsdb_idl_txn_insert( -+ struct ovsdb_idl_txn *, const struct ovsdb_idl_table_class *, -+ const struct uuid *); -+ -+struct ovsdb_idl *ovsdb_idl_txn_get_idl (struct ovsdb_idl_txn *); -+void ovsdb_idl_get_initial_snapshot(struct ovsdb_idl *); -+ -+ -+/* ovsdb_idl_loop provides an easy way to manage the transactions related -+ * to 'idl' and to cope with different status during transaction. */ -+struct ovsdb_idl_loop { -+ struct ovsdb_idl *idl; -+ unsigned int skip_seqno; -+ -+ struct ovsdb_idl_txn *committing_txn; -+ unsigned int precommit_seqno; -+ -+ struct ovsdb_idl_txn *open_txn; -+ -+ /* These members allow a client a simple, stateless way to keep track of -+ * transactions that commit: when a transaction commits successfully, -+ * ovsdb_idl_loop_commit_and_wait() copies 'next_cfg' to 'cur_cfg'. Thus, -+ * the client can set 'next_cfg' to a value that indicates a successful -+ * commit and check 'cur_cfg' on each iteration. */ -+ int64_t cur_cfg; -+ int64_t next_cfg; -+}; -+ -+#define OVSDB_IDL_LOOP_INITIALIZER(IDL) { .idl = (IDL) } -+ -+void ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *); -+struct ovsdb_idl_txn *ovsdb_idl_loop_run(struct ovsdb_idl_loop *); -+int ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *); -+ -+/* Conditional Replication -+ * ======================= -+ * -+ * By default, when the IDL replicates a particular table in the database, it -+ * replicates every row in the table. These functions allow the client to -+ * specify that only selected rows should be replicated, by constructing a -+ * per-table condition that specifies the rows to replicate. -+ * -+ * A condition is a disjunction of clauses. The condition is true, and thus a -+ * row is replicated, if any of the clauses evaluates to true for a given row. -+ * (Thus, a condition with no clauses is always false.) -+ */ -+ -+struct ovsdb_idl_condition { -+ struct hmap clauses; /* Contains "struct ovsdb_idl_clause"s. */ -+ bool is_true; /* Is the condition unconditionally true? */ -+}; -+#define OVSDB_IDL_CONDITION_INIT(CONDITION) \ -+ { HMAP_INITIALIZER(&(CONDITION)->clauses), false } -+ -+void ovsdb_idl_condition_init(struct ovsdb_idl_condition *); -+void ovsdb_idl_condition_clear(struct ovsdb_idl_condition *); -+void ovsdb_idl_condition_destroy(struct ovsdb_idl_condition *); -+void ovsdb_idl_condition_add_clause(struct ovsdb_idl_condition *, -+ enum ovsdb_function function, -+ const struct ovsdb_idl_column *column, -+ const struct ovsdb_datum *arg); -+void ovsdb_idl_condition_add_clause_true(struct ovsdb_idl_condition *); -+bool ovsdb_idl_condition_is_true(const struct ovsdb_idl_condition *); -+ -+unsigned int ovsdb_idl_set_condition(struct ovsdb_idl *, -+ const struct ovsdb_idl_table_class *, -+ const struct ovsdb_idl_condition *); -+ -+unsigned int ovsdb_idl_get_condition_seqno(const struct ovsdb_idl *); -+ -+/* Indexes over one or more columns in the IDL, to retrieve rows matching -+ * particular search criteria and to iterate over a subset of rows in a defined -+ * order. */ -+ -+enum ovsdb_index_order { -+ OVSDB_INDEX_ASC, /* 0, 1, 2, ... */ -+ OVSDB_INDEX_DESC /* 2, 1, 0, ... */ -+}; -+ -+typedef int column_comparator_func(const void *a, const void *b); -+ -+struct ovsdb_idl_index_column { -+ const struct ovsdb_idl_column *column; -+ column_comparator_func *comparer; -+ enum ovsdb_index_order order; -+}; -+ -+/* Creating an index. */ -+struct ovsdb_idl_index *ovsdb_idl_index_create( -+ struct ovsdb_idl *, const struct ovsdb_idl_index_column *, size_t n); -+struct ovsdb_idl_index *ovsdb_idl_index_create1( -+ struct ovsdb_idl *, const struct ovsdb_idl_column *); -+struct ovsdb_idl_index *ovsdb_idl_index_create2( -+ struct ovsdb_idl *, const struct ovsdb_idl_column *, -+ const struct ovsdb_idl_column *); -+ -+/* Searching an index. */ -+struct ovsdb_idl_row *ovsdb_idl_index_find(struct ovsdb_idl_index *, -+ const struct ovsdb_idl_row *); -+ -+/* Iteration over an index. -+ * -+ * Usually these would be invoked through table-specific wrappers generated -+ * by the IDL. */ -+ -+struct ovsdb_idl_cursor { -+ struct ovsdb_idl_index *index; /* Index being iterated. */ -+ struct skiplist_node *position; /* Current position in 'index'. */ -+}; -+ -+struct ovsdb_idl_cursor ovsdb_idl_cursor_first(struct ovsdb_idl_index *); -+struct ovsdb_idl_cursor ovsdb_idl_cursor_first_eq( -+ struct ovsdb_idl_index *, const struct ovsdb_idl_row *); -+struct ovsdb_idl_cursor ovsdb_idl_cursor_first_ge( -+ struct ovsdb_idl_index *, const struct ovsdb_idl_row *); -+ -+void ovsdb_idl_cursor_next(struct ovsdb_idl_cursor *); -+void ovsdb_idl_cursor_next_eq(struct ovsdb_idl_cursor *); -+ -+struct ovsdb_idl_row *ovsdb_idl_cursor_data(struct ovsdb_idl_cursor *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* ovsdb-idl.h */ -Index: openvswitch-2.17.2/lib/ovsdb-map-op.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-map-op.h -+++ /dev/null -@@ -1,53 +0,0 @@ --/* Copyright (C) 2016 Hewlett Packard Enterprise Development LP -- * All Rights Reserved. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); you may -- * not use this file except in compliance with the License. You may obtain -- * a copy of the License at -- * -- *     http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -- * License for the specific language governing permissions and limitations -- * under the License. -- */ -- --#ifndef OVSDB_MAP_OP_H --#define OVSDB_MAP_OP_H 1 -- --#include "ovsdb-data.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --enum map_op_type { -- MAP_OP_UPDATE, -- MAP_OP_INSERT, -- MAP_OP_DELETE --}; -- --struct map_op; /* Map Operation: a Partial Map Update */ --struct map_op_list; /* List of Map Operations */ -- --/* Map Operation functions */ --struct map_op *map_op_create(struct ovsdb_datum *, enum map_op_type); --void map_op_destroy(struct map_op *, const struct ovsdb_type *); --struct ovsdb_datum *map_op_datum(const struct map_op*); --enum map_op_type map_op_type(const struct map_op*); -- --/* Map Operation List functions */ --struct map_op_list *map_op_list_create(void); --void map_op_list_destroy(struct map_op_list *, const struct ovsdb_type *); --void map_op_list_add(struct map_op_list *, struct map_op *, -- const struct ovsdb_type *); --struct map_op *map_op_list_first(struct map_op_list *); --struct map_op *map_op_list_next(struct map_op_list *, struct map_op *); -- --#ifdef __cplusplus --} --#endif -- --#endif /* ovsdb-map-op.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-map-op.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-map-op.h -@@ -0,0 +1,53 @@ -+/* Copyright (C) 2016 Hewlett Packard Enterprise Development LP -+ * All Rights Reserved. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); you may -+ * not use this file except in compliance with the License. You may obtain -+ * a copy of the License at -+ * -+ *     http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+ * License for the specific language governing permissions and limitations -+ * under the License. -+ */ -+ -+#ifndef OVSDB_MAP_OP_H -+#define OVSDB_MAP_OP_H 1 -+ -+#include "openvswitch/ovsdb-data.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+enum map_op_type { -+ MAP_OP_UPDATE, -+ MAP_OP_INSERT, -+ MAP_OP_DELETE -+}; -+ -+struct map_op; /* Map Operation: a Partial Map Update */ -+struct map_op_list; /* List of Map Operations */ -+ -+/* Map Operation functions */ -+struct map_op *map_op_create(struct ovsdb_datum *, enum map_op_type); -+void map_op_destroy(struct map_op *, const struct ovsdb_type *); -+struct ovsdb_datum *map_op_datum(const struct map_op*); -+enum map_op_type map_op_type(const struct map_op*); -+ -+/* Map Operation List functions */ -+struct map_op_list *map_op_list_create(void); -+void map_op_list_destroy(struct map_op_list *, const struct ovsdb_type *); -+void map_op_list_add(struct map_op_list *, struct map_op *, -+ const struct ovsdb_type *); -+struct map_op *map_op_list_first(struct map_op_list *); -+struct map_op *map_op_list_next(struct map_op_list *, struct map_op *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* ovsdb-map-op.h */ -Index: openvswitch-2.17.2/lib/ovsdb-parser.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-parser.h -+++ /dev/null -@@ -1,81 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011, 2015, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_PARSER_H --#define OVSDB_PARSER_H 1 -- --#include --#include "openvswitch/compiler.h" --#include "openvswitch/json.h" --#include "sset.h" --#include "util.h" -- --struct ovsdb_parser { -- char *name; /* Used only in error messages. */ -- struct sset used; /* Already-parsed names from 'object'. */ -- const struct json *json; /* JSON object being parsed. */ -- struct ovsdb_error *error; /* Error signaled, if any. */ --}; -- --/* Check that the JSON types make the bitwise tricks below work OK. */ --BUILD_ASSERT_DECL(JSON_NULL >= 0 && JSON_NULL < 10); --BUILD_ASSERT_DECL(JSON_FALSE >= 0 && JSON_FALSE < 10); --BUILD_ASSERT_DECL(JSON_TRUE >= 0 && JSON_TRUE < 10); --BUILD_ASSERT_DECL(JSON_OBJECT >= 0 && JSON_OBJECT < 10); --BUILD_ASSERT_DECL(JSON_ARRAY >= 0 && JSON_ARRAY < 10); --BUILD_ASSERT_DECL(JSON_INTEGER >= 0 && JSON_INTEGER < 10); --BUILD_ASSERT_DECL(JSON_REAL >= 0 && JSON_REAL < 10); --BUILD_ASSERT_DECL(JSON_STRING >= 0 && JSON_STRING < 10); --BUILD_ASSERT_DECL(JSON_N_TYPES == 8); -- --enum ovsdb_parser_types { -- OP_NULL = 1 << JSON_NULL, /* null */ -- OP_FALSE = 1 << JSON_FALSE, /* false */ -- OP_TRUE = 1 << JSON_TRUE, /* true */ -- OP_OBJECT = 1 << JSON_OBJECT, /* {"a": b, "c": d, ...} */ -- OP_ARRAY = 1 << JSON_ARRAY, /* [1, 2, 3, ...] */ -- OP_INTEGER = 1 << JSON_INTEGER, /* 123. */ -- OP_NONINTEGER = 1 << JSON_REAL, /* 123.456. */ -- OP_STRING = 1 << JSON_STRING, /* "..." */ -- OP_ANY = (OP_NULL | OP_FALSE | OP_TRUE | OP_OBJECT | OP_ARRAY -- | OP_INTEGER | OP_NONINTEGER | OP_STRING), -- -- OP_BOOLEAN = OP_FALSE | OP_TRUE, -- OP_NUMBER = OP_INTEGER | OP_NONINTEGER, -- -- OP_ID = 1 << JSON_N_TYPES, /* "[_a-zA-Z][_a-zA-Z0-9]*" */ -- OP_OPTIONAL = 1 << (JSON_N_TYPES + 1) /* no value at all */ --}; -- --void ovsdb_parser_init(struct ovsdb_parser *, const struct json *, -- const char *name, ...) -- OVS_PRINTF_FORMAT(3, 4); --const struct json *ovsdb_parser_member(struct ovsdb_parser *, const char *name, -- enum ovsdb_parser_types); -- --void ovsdb_parser_raise_error(struct ovsdb_parser *parser, -- const char *format, ...) -- OVS_PRINTF_FORMAT(2, 3); --void ovsdb_parser_put_error(struct ovsdb_parser *, struct ovsdb_error *); --bool ovsdb_parser_has_error(const struct ovsdb_parser *); --struct ovsdb_error *ovsdb_parser_get_error(const struct ovsdb_parser *); --struct ovsdb_error *ovsdb_parser_finish(struct ovsdb_parser *) -- OVS_WARN_UNUSED_RESULT; --struct ovsdb_error *ovsdb_parser_destroy(struct ovsdb_parser *) -- OVS_WARN_UNUSED_RESULT; -- --bool ovsdb_parser_is_id(const char *string); -- --#endif /* ovsdb-parser.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-parser.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-parser.h -@@ -0,0 +1,89 @@ -+/* Copyright (c) 2009, 2010, 2011, 2015, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_PARSER_H -+#define OVSDB_PARSER_H 1 -+ -+#include -+#include "openvswitch/compiler.h" -+#include "openvswitch/json.h" -+#include "internal/sset.h" -+#include "internal/util.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct ovsdb_parser { -+ char *name; /* Used only in error messages. */ -+ struct sset used; /* Already-parsed names from 'object'. */ -+ const struct json *json; /* JSON object being parsed. */ -+ struct ovsdb_error *error; /* Error signaled, if any. */ -+}; -+ -+/* Check that the JSON types make the bitwise tricks below work OK. */ -+BUILD_ASSERT_DECL(JSON_NULL >= 0 && JSON_NULL < 10); -+BUILD_ASSERT_DECL(JSON_FALSE >= 0 && JSON_FALSE < 10); -+BUILD_ASSERT_DECL(JSON_TRUE >= 0 && JSON_TRUE < 10); -+BUILD_ASSERT_DECL(JSON_OBJECT >= 0 && JSON_OBJECT < 10); -+BUILD_ASSERT_DECL(JSON_ARRAY >= 0 && JSON_ARRAY < 10); -+BUILD_ASSERT_DECL(JSON_INTEGER >= 0 && JSON_INTEGER < 10); -+BUILD_ASSERT_DECL(JSON_REAL >= 0 && JSON_REAL < 10); -+BUILD_ASSERT_DECL(JSON_STRING >= 0 && JSON_STRING < 10); -+BUILD_ASSERT_DECL(JSON_N_TYPES == 8); -+ -+enum ovsdb_parser_types { -+ OP_NULL = 1 << JSON_NULL, /* null */ -+ OP_FALSE = 1 << JSON_FALSE, /* false */ -+ OP_TRUE = 1 << JSON_TRUE, /* true */ -+ OP_OBJECT = 1 << JSON_OBJECT, /* {"a": b, "c": d, ...} */ -+ OP_ARRAY = 1 << JSON_ARRAY, /* [1, 2, 3, ...] */ -+ OP_INTEGER = 1 << JSON_INTEGER, /* 123. */ -+ OP_NONINTEGER = 1 << JSON_REAL, /* 123.456. */ -+ OP_STRING = 1 << JSON_STRING, /* "..." */ -+ OP_ANY = (OP_NULL | OP_FALSE | OP_TRUE | OP_OBJECT | OP_ARRAY -+ | OP_INTEGER | OP_NONINTEGER | OP_STRING), -+ -+ OP_BOOLEAN = OP_FALSE | OP_TRUE, -+ OP_NUMBER = OP_INTEGER | OP_NONINTEGER, -+ -+ OP_ID = 1 << JSON_N_TYPES, /* "[_a-zA-Z][_a-zA-Z0-9]*" */ -+ OP_OPTIONAL = 1 << (JSON_N_TYPES + 1) /* no value at all */ -+}; -+ -+void ovsdb_parser_init(struct ovsdb_parser *, const struct json *, -+ const char *name, ...) -+ OVS_PRINTF_FORMAT(3, 4); -+const struct json *ovsdb_parser_member(struct ovsdb_parser *, const char *name, -+ enum ovsdb_parser_types); -+ -+void ovsdb_parser_raise_error(struct ovsdb_parser *parser, -+ const char *format, ...) -+ OVS_PRINTF_FORMAT(2, 3); -+void ovsdb_parser_put_error(struct ovsdb_parser *, struct ovsdb_error *); -+bool ovsdb_parser_has_error(const struct ovsdb_parser *); -+struct ovsdb_error *ovsdb_parser_get_error(const struct ovsdb_parser *); -+struct ovsdb_error *ovsdb_parser_finish(struct ovsdb_parser *) -+ OVS_WARN_UNUSED_RESULT; -+struct ovsdb_error *ovsdb_parser_destroy(struct ovsdb_parser *) -+ OVS_WARN_UNUSED_RESULT; -+ -+bool ovsdb_parser_is_id(const char *string); -+ -+#ifdef __cplusplus -+} // extern "C" -+#endif -+ -+#endif /* ovsdb-parser.h */ -Index: openvswitch-2.17.2/lib/ovsdb-set-op.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-set-op.h -+++ /dev/null -@@ -1,53 +0,0 @@ --/* Copyright (C) 2016 Hewlett Packard Enterprise Development LP -- * Copyright (C) 2016, IBM -- * All Rights Reserved. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); you may -- * not use this file except in compliance with the License. You may obtain -- * a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -- * License for the specific language governing permissions and limitations -- * under the License. -- */ -- --#ifndef OVSDB_SET_OP_H --#define OVSDB_SET_OP_H 1 -- --#include "ovsdb-data.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --enum set_op_type { -- SET_OP_INSERT, -- SET_OP_DELETE --}; -- --struct set_op; /* Set Operation: a Partial Set Update */ --struct set_op_list; /* List of Set Operations */ -- --/* Set Operation functions */ --struct set_op *set_op_create(struct ovsdb_datum *, enum set_op_type); --void set_op_destroy(struct set_op *, const struct ovsdb_type *); --struct ovsdb_datum *set_op_datum(const struct set_op*); --enum set_op_type set_op_type(const struct set_op*); -- --/* Set Operation List functions */ --struct set_op_list *set_op_list_create(void); --void set_op_list_destroy(struct set_op_list *, const struct ovsdb_type *); --void set_op_list_add(struct set_op_list *, struct set_op *, -- const struct ovsdb_type *); --struct set_op *set_op_list_first(struct set_op_list *); --struct set_op *set_op_list_next(struct set_op_list *, struct set_op *); -- --#ifdef __cplusplus --} --#endif -- --#endif /* ovsdb-set-op.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-set-op.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-set-op.h -@@ -0,0 +1,53 @@ -+/* Copyright (C) 2016 Hewlett Packard Enterprise Development LP -+ * Copyright (C) 2016, IBM -+ * All Rights Reserved. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); you may -+ * not use this file except in compliance with the License. You may obtain -+ * a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+ * License for the specific language governing permissions and limitations -+ * under the License. -+ */ -+ -+#ifndef OVSDB_SET_OP_H -+#define OVSDB_SET_OP_H 1 -+ -+#include "openvswitch/ovsdb-data.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+enum set_op_type { -+ SET_OP_INSERT, -+ SET_OP_DELETE -+}; -+ -+struct set_op; /* Set Operation: a Partial Set Update */ -+struct set_op_list; /* List of Set Operations */ -+ -+/* Set Operation functions */ -+struct set_op *set_op_create(struct ovsdb_datum *, enum set_op_type); -+void set_op_destroy(struct set_op *, const struct ovsdb_type *); -+struct ovsdb_datum *set_op_datum(const struct set_op*); -+enum set_op_type set_op_type(const struct set_op*); -+ -+/* Set Operation List functions */ -+struct set_op_list *set_op_list_create(void); -+void set_op_list_destroy(struct set_op_list *, const struct ovsdb_type *); -+void set_op_list_add(struct set_op_list *, struct set_op *, -+ const struct ovsdb_type *); -+struct set_op *set_op_list_first(struct set_op_list *); -+struct set_op *set_op_list_next(struct set_op_list *, struct set_op *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* ovsdb-set-op.h */ -Index: openvswitch-2.17.2/lib/ovsdb-types.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-types.h -+++ /dev/null -@@ -1,242 +0,0 @@ --/* Copyright (c) 2009, 2010, 2011 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef OVSDB_TYPES_H --#define OVSDB_TYPES_H 1 -- --#include --#include --#include --#include "openvswitch/compiler.h" --#include "uuid.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --struct json; -- --/* An atomic type: one that OVSDB regards as a single unit of data. */ --enum ovsdb_atomic_type { -- OVSDB_TYPE_VOID, /* No value. */ -- OVSDB_TYPE_INTEGER, /* Signed 64-bit integer. */ -- OVSDB_TYPE_REAL, /* IEEE 754 double-precision floating point. */ -- OVSDB_TYPE_BOOLEAN, /* True or false. */ -- OVSDB_TYPE_STRING, /* UTF-8 string. */ -- OVSDB_TYPE_UUID, /* RFC 4122 UUID referencing a table row. */ -- OVSDB_N_TYPES --}; -- --static inline bool ovsdb_atomic_type_is_valid(enum ovsdb_atomic_type); --bool ovsdb_atomic_type_from_string(const char *, enum ovsdb_atomic_type *); --struct ovsdb_error *ovsdb_atomic_type_from_json(enum ovsdb_atomic_type *, -- const struct json *); --const char *ovsdb_atomic_type_to_string(enum ovsdb_atomic_type); --struct json *ovsdb_atomic_type_to_json(enum ovsdb_atomic_type); -- --/* An atomic type plus optional constraints. */ -- --enum ovsdb_ref_type { -- OVSDB_REF_STRONG, /* Target must exist. */ -- OVSDB_REF_WEAK /* Delete reference if target disappears. */ --}; -- --struct ovsdb_integer_constraints { -- int64_t min; /* minInteger or INT64_MIN. */ -- int64_t max; /* maxInteger or INT64_MAX. */ --}; -- --struct ovsdb_real_constraints { -- double min; /* minReal or -DBL_MAX. */ -- double max; /* minReal or DBL_MAX. */ --}; -- --struct ovsdb_string_constraints { -- unsigned int minLen; /* minLength or 0. */ -- unsigned int maxLen; /* maxLength or UINT_MAX. */ --}; -- --struct ovsdb_uuid_constraints { -- char *refTableName; /* Name of referenced table, or NULL. */ -- struct ovsdb_table *refTable; /* Referenced table, if available. */ -- enum ovsdb_ref_type refType; /* Reference type. */ --}; -- --struct ovsdb_base_type { -- enum ovsdb_atomic_type type; -- -- /* If nonnull, a datum with keys of type 'type' that expresses all the -- * valid values for this base_type. */ -- struct ovsdb_datum *enum_; -- -- union { -- struct ovsdb_integer_constraints integer; -- struct ovsdb_real_constraints real; -- /* No constraints for Boolean types. */ -- struct ovsdb_string_constraints string; -- struct ovsdb_uuid_constraints uuid; -- }; --}; -- --#define OVSDB_BASE_VOID_INIT { .type = OVSDB_TYPE_VOID } --#define OVSDB_BASE_INTEGER_INIT { .type = OVSDB_TYPE_INTEGER, \ -- .integer = { INT64_MIN, INT64_MAX } } --#define OVSDB_BASE_REAL_INIT { .type = OVSDB_TYPE_REAL, \ -- .real = { -DBL_MAX, DBL_MAX } } --#define OVSDB_BASE_BOOLEAN_INIT { .type = OVSDB_TYPE_BOOLEAN } --#define OVSDB_BASE_STRING_INIT { .type = OVSDB_TYPE_STRING, \ -- .string = { 0, UINT_MAX } } --#define OVSDB_BASE_UUID_INIT { .type = OVSDB_TYPE_UUID, \ -- .uuid = { NULL, NULL, 0 } } -- --void ovsdb_base_type_init(struct ovsdb_base_type *, enum ovsdb_atomic_type); --void ovsdb_base_type_clone(struct ovsdb_base_type *, -- const struct ovsdb_base_type *); --void ovsdb_base_type_destroy(struct ovsdb_base_type *); -- --bool ovsdb_base_type_is_valid(const struct ovsdb_base_type *); --bool ovsdb_base_type_has_constraints(const struct ovsdb_base_type *); --void ovsdb_base_type_clear_constraints(struct ovsdb_base_type *); --const struct ovsdb_type *ovsdb_base_type_get_enum_type(enum ovsdb_atomic_type); -- --struct ovsdb_error *ovsdb_base_type_from_json(struct ovsdb_base_type *, -- const struct json *) -- OVS_WARN_UNUSED_RESULT; --struct json *ovsdb_base_type_to_json(const struct ovsdb_base_type *); -- --static inline bool ovsdb_base_type_is_ref(const struct ovsdb_base_type *); --static inline bool ovsdb_base_type_is_strong_ref( -- const struct ovsdb_base_type *); --static inline bool ovsdb_base_type_is_weak_ref(const struct ovsdb_base_type *); -- --/* An OVSDB type. -- * -- * Several rules constrain the valid types. See ovsdb_type_is_valid() (in -- * ovsdb-types.c) for details. -- * -- * If 'value_type' is OVSDB_TYPE_VOID, 'n_min' is 1, and 'n_max' is 1, then the -- * type is a single atomic 'key_type'. -- * -- * If 'value_type' is OVSDB_TYPE_VOID and 'n_min' or 'n_max' (or both) has a -- * value other than 1, then the type is a set of 'key_type'. If 'n_min' is 0 -- * and 'n_max' is 1, then the type can also be considered an optional -- * 'key_type'. -- * -- * If 'value_type' is not OVSDB_TYPE_VOID, then the type is a map from -- * 'key_type' to 'value_type'. If 'n_min' is 0 and 'n_max' is 1, then the type -- * can also be considered an optional pair of 'key_type' and 'value_type'. -- */ --struct ovsdb_type { -- struct ovsdb_base_type key; -- struct ovsdb_base_type value; -- unsigned int n_min; -- unsigned int n_max; /* UINT_MAX stands in for "unlimited". */ --}; -- --#define OVSDB_TYPE_SCALAR_INITIALIZER(KEY) { KEY, OVSDB_BASE_VOID_INIT, 1, 1 } -- --extern const struct ovsdb_type ovsdb_type_integer; --extern const struct ovsdb_type ovsdb_type_real; --extern const struct ovsdb_type ovsdb_type_boolean; --extern const struct ovsdb_type ovsdb_type_string; --extern const struct ovsdb_type ovsdb_type_uuid; -- --void ovsdb_type_clone(struct ovsdb_type *, const struct ovsdb_type *); --void ovsdb_type_destroy(struct ovsdb_type *); -- --bool ovsdb_type_is_valid(const struct ovsdb_type *); -- --static inline bool ovsdb_type_is_scalar(const struct ovsdb_type *); --static inline bool ovsdb_type_is_optional(const struct ovsdb_type *); --static inline bool ovsdb_type_is_optional_scalar( -- const struct ovsdb_type *); --static inline bool ovsdb_type_is_composite(const struct ovsdb_type *); --static inline bool ovsdb_type_is_set(const struct ovsdb_type *); --static inline bool ovsdb_type_is_map(const struct ovsdb_type *); -- --char *ovsdb_type_to_english(const struct ovsdb_type *); -- --struct ovsdb_error *ovsdb_type_from_json(struct ovsdb_type *, -- const struct json *) -- OVS_WARN_UNUSED_RESULT; --struct json *ovsdb_type_to_json(const struct ovsdb_type *); -- --/* Inline function implementations. */ -- --static inline bool --ovsdb_atomic_type_is_valid(enum ovsdb_atomic_type atomic_type) --{ -- return (int) atomic_type >= 0 && atomic_type < OVSDB_N_TYPES; --} -- --static inline bool --ovsdb_base_type_is_ref(const struct ovsdb_base_type *base) --{ -- return base->type == OVSDB_TYPE_UUID && base->uuid.refTableName; --} -- --static inline bool --ovsdb_base_type_is_strong_ref(const struct ovsdb_base_type *base) --{ -- return (ovsdb_base_type_is_ref(base) -- && base->uuid.refType == OVSDB_REF_STRONG); --} -- --static inline bool --ovsdb_base_type_is_weak_ref(const struct ovsdb_base_type *base) --{ -- return (ovsdb_base_type_is_ref(base) -- && base->uuid.refType == OVSDB_REF_WEAK); --} -- --static inline bool ovsdb_type_is_scalar(const struct ovsdb_type *type) --{ -- return (type->value.type == OVSDB_TYPE_VOID -- && type->n_min == 1 && type->n_max == 1); --} -- --static inline bool ovsdb_type_is_optional(const struct ovsdb_type *type) --{ -- return type->n_min == 0; --} -- --static inline bool ovsdb_type_is_optional_scalar( -- const struct ovsdb_type *type) --{ -- return (type->value.type == OVSDB_TYPE_VOID -- && type->n_min == 0 && type->n_max == 1); --} -- --static inline bool ovsdb_type_is_composite(const struct ovsdb_type *type) --{ -- return type->n_max > 1; --} -- --static inline bool ovsdb_type_is_set(const struct ovsdb_type *type) --{ -- return (type->value.type == OVSDB_TYPE_VOID -- && (type->n_min != 1 || type->n_max != 1)); --} -- --static inline bool ovsdb_type_is_map(const struct ovsdb_type *type) --{ -- return type->value.type != OVSDB_TYPE_VOID; --} -- --#ifdef __cplusplus --} --#endif -- --#endif /* ovsdb-types.h */ -Index: openvswitch-2.17.2/include/openvswitch/ovsdb-types.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/openvswitch/ovsdb-types.h -@@ -0,0 +1,242 @@ -+/* Copyright (c) 2009, 2010, 2011 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef OVSDB_TYPES_H -+#define OVSDB_TYPES_H 1 -+ -+#include -+#include -+#include -+#include "openvswitch/compiler.h" -+#include "internal/uuid.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct json; -+ -+/* An atomic type: one that OVSDB regards as a single unit of data. */ -+enum ovsdb_atomic_type { -+ OVSDB_TYPE_VOID, /* No value. */ -+ OVSDB_TYPE_INTEGER, /* Signed 64-bit integer. */ -+ OVSDB_TYPE_REAL, /* IEEE 754 double-precision floating point. */ -+ OVSDB_TYPE_BOOLEAN, /* True or false. */ -+ OVSDB_TYPE_STRING, /* UTF-8 string. */ -+ OVSDB_TYPE_UUID, /* RFC 4122 UUID referencing a table row. */ -+ OVSDB_N_TYPES -+}; -+ -+static inline bool ovsdb_atomic_type_is_valid(enum ovsdb_atomic_type); -+bool ovsdb_atomic_type_from_string(const char *, enum ovsdb_atomic_type *); -+struct ovsdb_error *ovsdb_atomic_type_from_json(enum ovsdb_atomic_type *, -+ const struct json *); -+const char *ovsdb_atomic_type_to_string(enum ovsdb_atomic_type); -+struct json *ovsdb_atomic_type_to_json(enum ovsdb_atomic_type); -+ -+/* An atomic type plus optional constraints. */ -+ -+enum ovsdb_ref_type { -+ OVSDB_REF_STRONG, /* Target must exist. */ -+ OVSDB_REF_WEAK /* Delete reference if target disappears. */ -+}; -+ -+struct ovsdb_integer_constraints { -+ int64_t min; /* minInteger or INT64_MIN. */ -+ int64_t max; /* maxInteger or INT64_MAX. */ -+}; -+ -+struct ovsdb_real_constraints { -+ double min; /* minReal or -DBL_MAX. */ -+ double max; /* minReal or DBL_MAX. */ -+}; -+ -+struct ovsdb_string_constraints { -+ unsigned int minLen; /* minLength or 0. */ -+ unsigned int maxLen; /* maxLength or UINT_MAX. */ -+}; -+ -+struct ovsdb_uuid_constraints { -+ char *refTableName; /* Name of referenced table, or NULL. */ -+ struct ovsdb_table *refTable; /* Referenced table, if available. */ -+ enum ovsdb_ref_type refType; /* Reference type. */ -+}; -+ -+struct ovsdb_base_type { -+ enum ovsdb_atomic_type type; -+ -+ /* If nonnull, a datum with keys of type 'type' that expresses all the -+ * valid values for this base_type. */ -+ struct ovsdb_datum *enum_; -+ -+ union { -+ struct ovsdb_integer_constraints integer; -+ struct ovsdb_real_constraints real; -+ /* No constraints for Boolean types. */ -+ struct ovsdb_string_constraints string; -+ struct ovsdb_uuid_constraints uuid; -+ }; -+}; -+ -+#define OVSDB_BASE_VOID_INIT { .type = OVSDB_TYPE_VOID } -+#define OVSDB_BASE_INTEGER_INIT { .type = OVSDB_TYPE_INTEGER, \ -+ .integer = { INT64_MIN, INT64_MAX } } -+#define OVSDB_BASE_REAL_INIT { .type = OVSDB_TYPE_REAL, \ -+ .real = { -DBL_MAX, DBL_MAX } } -+#define OVSDB_BASE_BOOLEAN_INIT { .type = OVSDB_TYPE_BOOLEAN } -+#define OVSDB_BASE_STRING_INIT { .type = OVSDB_TYPE_STRING, \ -+ .string = { 0, UINT_MAX } } -+#define OVSDB_BASE_UUID_INIT { .type = OVSDB_TYPE_UUID, \ -+ .uuid = { NULL, NULL, 0 } } -+ -+void ovsdb_base_type_init(struct ovsdb_base_type *, enum ovsdb_atomic_type); -+void ovsdb_base_type_clone(struct ovsdb_base_type *, -+ const struct ovsdb_base_type *); -+void ovsdb_base_type_destroy(struct ovsdb_base_type *); -+ -+bool ovsdb_base_type_is_valid(const struct ovsdb_base_type *); -+bool ovsdb_base_type_has_constraints(const struct ovsdb_base_type *); -+void ovsdb_base_type_clear_constraints(struct ovsdb_base_type *); -+const struct ovsdb_type *ovsdb_base_type_get_enum_type(enum ovsdb_atomic_type); -+ -+struct ovsdb_error *ovsdb_base_type_from_json(struct ovsdb_base_type *, -+ const struct json *) -+ OVS_WARN_UNUSED_RESULT; -+struct json *ovsdb_base_type_to_json(const struct ovsdb_base_type *); -+ -+static inline bool ovsdb_base_type_is_ref(const struct ovsdb_base_type *); -+static inline bool ovsdb_base_type_is_strong_ref( -+ const struct ovsdb_base_type *); -+static inline bool ovsdb_base_type_is_weak_ref(const struct ovsdb_base_type *); -+ -+/* An OVSDB type. -+ * -+ * Several rules constrain the valid types. See ovsdb_type_is_valid() (in -+ * ovsdb-types.c) for details. -+ * -+ * If 'value_type' is OVSDB_TYPE_VOID, 'n_min' is 1, and 'n_max' is 1, then the -+ * type is a single atomic 'key_type'. -+ * -+ * If 'value_type' is OVSDB_TYPE_VOID and 'n_min' or 'n_max' (or both) has a -+ * value other than 1, then the type is a set of 'key_type'. If 'n_min' is 0 -+ * and 'n_max' is 1, then the type can also be considered an optional -+ * 'key_type'. -+ * -+ * If 'value_type' is not OVSDB_TYPE_VOID, then the type is a map from -+ * 'key_type' to 'value_type'. If 'n_min' is 0 and 'n_max' is 1, then the type -+ * can also be considered an optional pair of 'key_type' and 'value_type'. -+ */ -+struct ovsdb_type { -+ struct ovsdb_base_type key; -+ struct ovsdb_base_type value; -+ unsigned int n_min; -+ unsigned int n_max; /* UINT_MAX stands in for "unlimited". */ -+}; -+ -+#define OVSDB_TYPE_SCALAR_INITIALIZER(KEY) { KEY, OVSDB_BASE_VOID_INIT, 1, 1 } -+ -+extern const struct ovsdb_type ovsdb_type_integer; -+extern const struct ovsdb_type ovsdb_type_real; -+extern const struct ovsdb_type ovsdb_type_boolean; -+extern const struct ovsdb_type ovsdb_type_string; -+extern const struct ovsdb_type ovsdb_type_uuid; -+ -+void ovsdb_type_clone(struct ovsdb_type *, const struct ovsdb_type *); -+void ovsdb_type_destroy(struct ovsdb_type *); -+ -+bool ovsdb_type_is_valid(const struct ovsdb_type *); -+ -+static inline bool ovsdb_type_is_scalar(const struct ovsdb_type *); -+static inline bool ovsdb_type_is_optional(const struct ovsdb_type *); -+static inline bool ovsdb_type_is_optional_scalar( -+ const struct ovsdb_type *); -+static inline bool ovsdb_type_is_composite(const struct ovsdb_type *); -+static inline bool ovsdb_type_is_set(const struct ovsdb_type *); -+static inline bool ovsdb_type_is_map(const struct ovsdb_type *); -+ -+char *ovsdb_type_to_english(const struct ovsdb_type *); -+ -+struct ovsdb_error *ovsdb_type_from_json(struct ovsdb_type *, -+ const struct json *) -+ OVS_WARN_UNUSED_RESULT; -+struct json *ovsdb_type_to_json(const struct ovsdb_type *); -+ -+/* Inline function implementations. */ -+ -+static inline bool -+ovsdb_atomic_type_is_valid(enum ovsdb_atomic_type atomic_type) -+{ -+ return (int) atomic_type >= 0 && atomic_type < OVSDB_N_TYPES; -+} -+ -+static inline bool -+ovsdb_base_type_is_ref(const struct ovsdb_base_type *base) -+{ -+ return base->type == OVSDB_TYPE_UUID && base->uuid.refTableName; -+} -+ -+static inline bool -+ovsdb_base_type_is_strong_ref(const struct ovsdb_base_type *base) -+{ -+ return (ovsdb_base_type_is_ref(base) -+ && base->uuid.refType == OVSDB_REF_STRONG); -+} -+ -+static inline bool -+ovsdb_base_type_is_weak_ref(const struct ovsdb_base_type *base) -+{ -+ return (ovsdb_base_type_is_ref(base) -+ && base->uuid.refType == OVSDB_REF_WEAK); -+} -+ -+static inline bool ovsdb_type_is_scalar(const struct ovsdb_type *type) -+{ -+ return (type->value.type == OVSDB_TYPE_VOID -+ && type->n_min == 1 && type->n_max == 1); -+} -+ -+static inline bool ovsdb_type_is_optional(const struct ovsdb_type *type) -+{ -+ return type->n_min == 0; -+} -+ -+static inline bool ovsdb_type_is_optional_scalar( -+ const struct ovsdb_type *type) -+{ -+ return (type->value.type == OVSDB_TYPE_VOID -+ && type->n_min == 0 && type->n_max == 1); -+} -+ -+static inline bool ovsdb_type_is_composite(const struct ovsdb_type *type) -+{ -+ return type->n_max > 1; -+} -+ -+static inline bool ovsdb_type_is_set(const struct ovsdb_type *type) -+{ -+ return (type->value.type == OVSDB_TYPE_VOID -+ && (type->n_min != 1 || type->n_max != 1)); -+} -+ -+static inline bool ovsdb_type_is_map(const struct ovsdb_type *type) -+{ -+ return type->value.type != OVSDB_TYPE_VOID; -+} -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* ovsdb-types.h */ -Index: openvswitch-2.17.2/include/sparse/automake.mk -=================================================================== ---- openvswitch-2.17.2.orig/include/sparse/automake.mk -+++ openvswitch-2.17.2/include/sparse/automake.mk -@@ -1,4 +1,4 @@ --noinst_HEADERS += \ -+sparse_headers = \ - include/sparse/rte_byteorder.h \ - include/sparse/xmmintrin.h \ - include/sparse/arpa/inet.h \ -@@ -21,3 +21,11 @@ noinst_HEADERS += \ - include/sparse/threads.h \ - include/sparse/linux/if_packet.h \ - include/sparse/linux/tc_act/tc_pedit.h -+ -+# Only install headers if enabled -+if ENABLE_SPARSE_BY_DEFAULT -+ ovssparseincludedir = $(openvswitchincludedir)/sparse -+ ovssparseinclude_HEADERS = $(sparse_headers) -+else -+ noinst_HEADERS += $(sparse_headers) -+endif -Index: openvswitch-2.17.2/include/windows/netinet/icmp6.h -=================================================================== ---- openvswitch-2.17.2.orig/include/windows/netinet/icmp6.h -+++ openvswitch-2.17.2/include/windows/netinet/icmp6.h -@@ -61,7 +61,7 @@ - #ifndef _NETINET_ICMP6_H_ - #define _NETINET_ICMP6_H_ - --#include "byte-order.h" -+#include "internal/byte-order.h" - - #define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr) - - sizeof(struct icmp6_hdr) */ -Index: openvswitch-2.17.2/include/windows/netinet/ip6.h -=================================================================== ---- openvswitch-2.17.2.orig/include/windows/netinet/ip6.h -+++ openvswitch-2.17.2/include/windows/netinet/ip6.h -@@ -62,7 +62,7 @@ - #define _NETINET_IP6_H_ - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - - /* - * Definition for internet protocol version 6. -Index: openvswitch-2.17.2/lib/aes128.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/aes128.c -+++ openvswitch-2.17.2/lib/aes128.c -@@ -26,7 +26,7 @@ - - #include "aes128.h" - --#include "util.h" -+#include "internal/util.h" - - static const uint32_t Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, -Index: openvswitch-2.17.2/lib/async-append-aio.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/async-append-aio.c -+++ openvswitch-2.17.2/lib/async-append-aio.c -@@ -26,8 +26,8 @@ - #include - - #include "byteq.h" --#include "ovs-thread.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/util.h" - - /* Maximum number of bytes of buffered data. */ - enum { BUFFER_SIZE = 65536 }; -Index: openvswitch-2.17.2/lib/async-append-null.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/async-append-null.c -+++ openvswitch-2.17.2/lib/async-append-null.c -@@ -23,7 +23,7 @@ - #include - #include - --#include "util.h" -+#include "internal/util.h" - - struct async_append * - async_append_create(int fd OVS_UNUSED) -Index: openvswitch-2.17.2/lib/automake.mk -=================================================================== ---- openvswitch-2.17.2.orig/lib/automake.mk -+++ openvswitch-2.17.2/lib/automake.mk -@@ -237,31 +237,15 @@ lib_libopenvswitch_la_SOURCES = \ - lib/ofp-version-opt.h \ - lib/ofp-version-opt.c \ - lib/ofpbuf.c \ -- lib/ovs-atomic-c++.h \ -- lib/ovs-atomic-c11.h \ -- lib/ovs-atomic-clang.h \ -- lib/ovs-atomic-flag-gcc4.7+.h \ -- lib/ovs-atomic-gcc4+.h \ -- lib/ovs-atomic-gcc4.7+.h \ -- lib/ovs-atomic-i586.h \ -- lib/ovs-atomic-locked.c \ -- lib/ovs-atomic-locked.h \ -- lib/ovs-atomic-msvc.h \ -- lib/ovs-atomic-pthreads.h \ -- lib/ovs-atomic-x86_64.h \ -- lib/ovs-atomic.h \ - lib/ovs-lldp.c \ - lib/ovs-lldp.h \ - lib/ovs-numa.c \ -- lib/ovs-numa.h \ - lib/ovs-rcu.c \ -- lib/ovs-rcu.h \ - lib/ovs-replay.c \ - lib/ovs-replay.h \ - lib/ovs-router.h \ - lib/ovs-router.c \ - lib/ovs-thread.c \ -- lib/ovs-thread.h \ - lib/ovsdb-cs.c \ - lib/ovsdb-cs.h \ - lib/ovsdb-data.c \ -Index: openvswitch-2.17.2/lib/backtrace.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/backtrace.c -+++ openvswitch-2.17.2/lib/backtrace.c -@@ -23,7 +23,7 @@ - - #include "backtrace.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(backtrace); - -Index: openvswitch-2.17.2/lib/bfd.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/bfd.c -+++ openvswitch-2.17.2/lib/bfd.c -@@ -22,30 +22,30 @@ - #include - #include - --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "connectivity.h" --#include "csum.h" --#include "dp-packet.h" -+#include "internal/csum.h" -+#include "internal/dp-packet.h" - #include "dpif.h" - #include "openvswitch/dynamic-string.h" --#include "flow.h" --#include "hash.h" -+#include "internal/flow.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "odp-util.h" - #include "openvswitch/ofpbuf.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/types.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "random.h" --#include "seq.h" --#include "smap.h" --#include "timeval.h" --#include "unaligned.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/seq.h" -+#include "internal/smap.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(bfd); -Index: openvswitch-2.17.2/lib/bfd.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/bfd.h -+++ openvswitch-2.17.2/lib/bfd.h -@@ -21,7 +21,7 @@ - #include - #include - --#include "packets.h" -+#include "internal/packets.h" - - struct bfd; - struct dpif_flow_stats; -Index: openvswitch-2.17.2/lib/bundle.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/bundle.c -+++ openvswitch-2.17.2/lib/bundle.c -@@ -15,16 +15,16 @@ - - #include - --#include "bundle.h" -+#include "internal/bundle.h" - - #include - #include - #include - #include - --#include "colors.h" -+#include "internal/colors.h" - #include "multipath.h" --#include "nx-match.h" -+#include "internal/nx-match.h" - #include "openflow/nicira-ext.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/meta-flow.h" -@@ -33,7 +33,7 @@ - #include "openvswitch/ofp-port.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(bundle); - -Index: openvswitch-2.17.2/lib/byteq.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/byteq.c -+++ openvswitch-2.17.2/lib/byteq.c -@@ -18,7 +18,7 @@ - #include - #include - #include --#include "util.h" -+#include "internal/util.h" - - /* Initializes 'q' as an empty byteq that uses the 'size' bytes of 'buffer' to - * store data. 'size' must be a power of 2. -Index: openvswitch-2.17.2/lib/ccmap.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ccmap.c -+++ openvswitch-2.17.2/lib/ccmap.c -@@ -16,12 +16,12 @@ - - #include - #include "ccmap.h" --#include "coverage.h" --#include "bitmap.h" --#include "hash.h" --#include "ovs-rcu.h" --#include "random.h" --#include "util.h" -+#include "internal/coverage.h" -+#include "internal/bitmap.h" -+#include "internal/hash.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/random.h" -+#include "internal/util.h" - - COVERAGE_DEFINE(ccmap_expand); - COVERAGE_DEFINE(ccmap_shrink); -Index: openvswitch-2.17.2/lib/ccmap.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ccmap.h -+++ openvswitch-2.17.2/lib/ccmap.h -@@ -19,8 +19,8 @@ - - #include - #include --#include "ovs-rcu.h" --#include "util.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/util.h" - - /* Concurrent hash map for numerical counts of given hash values. - * ============================================================== -Index: openvswitch-2.17.2/lib/cfm.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/cfm.c -+++ openvswitch-2.17.2/lib/cfm.c -@@ -21,24 +21,24 @@ - #include - #include - --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "connectivity.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/dynamic-string.h" --#include "flow.h" --#include "hash.h" -+#include "internal/flow.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "netdev.h" --#include "ovs-atomic.h" --#include "packets.h" -+#include "internal/netdev.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "random.h" --#include "seq.h" --#include "timer.h" --#include "timeval.h" --#include "unixctl.h" -+#include "internal/random.h" -+#include "internal/seq.h" -+#include "internal/timer.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(cfm); - -Index: openvswitch-2.17.2/lib/cfm.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/cfm.h -+++ openvswitch-2.17.2/lib/cfm.h -@@ -20,7 +20,7 @@ - - #include "openvswitch/hmap.h" - #include "openvswitch/types.h" --#include "packets.h" -+#include "internal/packets.h" - - struct flow; - struct dp_packet; -Index: openvswitch-2.17.2/lib/classifier-private.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/classifier-private.h -+++ openvswitch-2.17.2/lib/classifier-private.h -@@ -18,10 +18,10 @@ - #define CLASSIFIER_PRIVATE_H 1 - - #include "ccmap.h" --#include "cmap.h" --#include "flow.h" --#include "hash.h" --#include "rculist.h" -+#include "internal/cmap.h" -+#include "internal/flow.h" -+#include "internal/hash.h" -+#include "internal/rculist.h" - - /* Classifier internal definitions, subject to change at any time. */ - -Index: openvswitch-2.17.2/lib/classifier.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/classifier.c -+++ openvswitch-2.17.2/lib/classifier.c -@@ -15,16 +15,16 @@ - */ - - #include --#include "classifier.h" -+#include "internal/classifier.h" - #include "classifier-private.h" - #include - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/dynamic-string.h" - #include "odp-util.h" --#include "packets.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/util.h" - - struct trie_ctx; - -Index: openvswitch-2.17.2/lib/cmap.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/cmap.c -+++ openvswitch-2.17.2/lib/cmap.c -@@ -15,13 +15,13 @@ - */ - - #include --#include "cmap.h" --#include "coverage.h" --#include "bitmap.h" --#include "hash.h" --#include "ovs-rcu.h" --#include "random.h" --#include "util.h" -+#include "internal/cmap.h" -+#include "internal/coverage.h" -+#include "internal/bitmap.h" -+#include "internal/hash.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/random.h" -+#include "internal/util.h" - - COVERAGE_DEFINE(cmap_expand); - COVERAGE_DEFINE(cmap_shrink); -Index: openvswitch-2.17.2/lib/colors.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/colors.c -+++ openvswitch-2.17.2/lib/colors.c -@@ -18,12 +18,12 @@ - - #include - --#include "colors.h" -+#include "internal/colors.h" - - #include - #include - --#include "util.h" -+#include "internal/util.h" - - struct color_key { - const char *name; -Index: openvswitch-2.17.2/lib/command-line.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/command-line.c -+++ openvswitch-2.17.2/lib/command-line.c -@@ -15,14 +15,14 @@ - */ - - #include --#include "command-line.h" -+#include "internal/command-line.h" - #include - #include - #include --#include "svec.h" -+#include "internal/svec.h" - #include "openvswitch/dynamic-string.h" --#include "ovs-thread.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(command_line); -Index: openvswitch-2.17.2/lib/connectivity.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/connectivity.c -+++ openvswitch-2.17.2/lib/connectivity.c -@@ -16,8 +16,8 @@ - - #include - #include "connectivity.h" --#include "ovs-thread.h" --#include "seq.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/seq.h" - - static struct seq *connectivity_seq; - -Index: openvswitch-2.17.2/lib/conntrack-icmp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/conntrack-icmp.c -+++ openvswitch-2.17.2/lib/conntrack-icmp.c -@@ -23,7 +23,7 @@ - - #include "conntrack-private.h" - #include "conntrack-tp.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - - enum OVS_PACKED_ENUM icmp_state { - ICMPS_FIRST, -Index: openvswitch-2.17.2/lib/conntrack-other.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/conntrack-other.c -+++ openvswitch-2.17.2/lib/conntrack-other.c -@@ -18,7 +18,7 @@ - - #include "conntrack-private.h" - #include "conntrack-tp.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - - enum OVS_PACKED_ENUM other_state { - OTHERS_FIRST, -Index: openvswitch-2.17.2/lib/conntrack-private.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/conntrack-private.h -+++ openvswitch-2.17.2/lib/conntrack-private.h -@@ -21,16 +21,16 @@ - #include - #include - --#include "cmap.h" -+#include "internal/cmap.h" - #include "conntrack.h" - #include "ct-dpif.h" - #include "ipf.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" - #include "openvswitch/types.h" --#include "packets.h" --#include "unaligned.h" --#include "dp-packet.h" -+#include "internal/packets.h" -+#include "internal/unaligned.h" -+#include "internal/dp-packet.h" - - struct ct_endpoint { - union ct_addr addr; -Index: openvswitch-2.17.2/lib/conntrack-tcp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/conntrack-tcp.c -+++ openvswitch-2.17.2/lib/conntrack-tcp.c -@@ -40,10 +40,10 @@ - - #include "conntrack-private.h" - #include "conntrack-tp.h" --#include "coverage.h" -+#include "internal/coverage.h" - #include "ct-dpif.h" --#include "dp-packet.h" --#include "util.h" -+#include "internal/dp-packet.h" -+#include "internal/util.h" - - COVERAGE_DEFINE(conntrack_tcp_seq_chk_bypass); - COVERAGE_DEFINE(conntrack_tcp_seq_chk_failed); -Index: openvswitch-2.17.2/lib/conntrack.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/conntrack.c -+++ openvswitch-2.17.2/lib/conntrack.c -@@ -22,24 +22,24 @@ - #include - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "conntrack.h" - #include "conntrack-private.h" - #include "conntrack-tp.h" --#include "coverage.h" --#include "csum.h" -+#include "internal/coverage.h" -+#include "internal/csum.h" - #include "ct-dpif.h" --#include "dp-packet.h" --#include "flow.h" --#include "netdev.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" -+#include "internal/netdev.h" - #include "odp-netlink.h" - #include "openvswitch/hmap.h" - #include "openvswitch/vlog.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" --#include "random.h" --#include "timeval.h" -+#include "internal/random.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(conntrack); - -Index: openvswitch-2.17.2/lib/conntrack.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/conntrack.h -+++ openvswitch-2.17.2/lib/conntrack.h -@@ -19,18 +19,18 @@ - - #include - --#include "cmap.h" -+#include "internal/cmap.h" - #include "ct-dpif.h" --#include "latch.h" -+#include "internal/latch.h" - #include "odp-netlink.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" - #include "openvswitch/thread.h" - #include "openvswitch/types.h" --#include "ovs-atomic.h" --#include "ovs-thread.h" --#include "packets.h" --#include "hindex.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/hindex.h" - - /* Userspace connection tracker - * ============================ -Index: openvswitch-2.17.2/lib/coverage.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/coverage.c -+++ openvswitch-2.17.2/lib/coverage.c -@@ -15,15 +15,15 @@ - */ - - #include --#include "coverage.h" -+#include "internal/coverage.h" - #include - #include - #include "openvswitch/dynamic-string.h" --#include "hash.h" --#include "svec.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/hash.h" -+#include "internal/svec.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(coverage); -Index: openvswitch-2.17.2/lib/crc32c.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/crc32c.c -+++ openvswitch-2.17.2/lib/crc32c.c -@@ -43,8 +43,8 @@ - */ - - #include --#include "crc32c.h" --#include "byte-order.h" -+#include "internal/crc32c.h" -+#include "internal/byte-order.h" - - /*****************************************************************/ - /* */ -Index: openvswitch-2.17.2/lib/csum.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/csum.c -+++ openvswitch-2.17.2/lib/csum.c -@@ -15,8 +15,8 @@ - */ - - #include --#include "csum.h" --#include "unaligned.h" -+#include "internal/csum.h" -+#include "internal/unaligned.h" - #include - #include - -Index: openvswitch-2.17.2/lib/ct-dpif.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ct-dpif.h -+++ openvswitch-2.17.2/lib/ct-dpif.h -@@ -18,7 +18,7 @@ - #define CT_DPIF_H - - #include "openvswitch/types.h" --#include "packets.h" -+#include "internal/packets.h" - - union ct_dpif_inet_addr { - ovs_be32 ip; -Index: openvswitch-2.17.2/lib/daemon-unix.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/daemon-unix.c -+++ openvswitch-2.17.2/lib/daemon-unix.c -@@ -16,7 +16,7 @@ - - #include - #include "backtrace.h" --#include "daemon.h" -+#include "internal/daemon.h" - #include "daemon-private.h" - #include - #include -@@ -32,15 +32,15 @@ - #if HAVE_LIBCAPNG - #include - #endif --#include "command-line.h" --#include "fatal-signal.h" --#include "dirs.h" -+#include "internal/command-line.h" -+#include "internal/fatal-signal.h" -+#include "internal/dirs.h" - #include "lockfile.h" --#include "ovs-thread.h" --#include "process.h" --#include "socket-util.h" --#include "timeval.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/process.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(daemon_unix); -Index: openvswitch-2.17.2/lib/daemon-windows.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/daemon-windows.c -+++ openvswitch-2.17.2/lib/daemon-windows.c -@@ -15,15 +15,15 @@ - */ - - #include --#include "daemon.h" -+#include "internal/daemon.h" - #include "daemon-private.h" - #include - #include - #include - #include --#include "dirs.h" --#include "fatal-signal.h" --#include "ovs-thread.h" -+#include "internal/dirs.h" -+#include "internal/fatal-signal.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/lib/daemon.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/daemon.c -+++ openvswitch-2.17.2/lib/daemon.c -@@ -14,13 +14,13 @@ - * limitations under the License. - */ - #include --#include "daemon.h" -+#include "internal/daemon.h" - #include "daemon-private.h" - #include - #include - #include --#include "util.h" --#include "ovs-thread.h" -+#include "internal/util.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(daemon); -Index: openvswitch-2.17.2/lib/db-ctl-base.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/db-ctl-base.c -+++ openvswitch-2.17.2/lib/db-ctl-base.c -@@ -20,24 +20,25 @@ - #include - #include - --#include "db-ctl-base.h" -+#include "internal/db-ctl-base.h" - -+#include "internal/command-line.h" - #include "openvswitch/compiler.h" --#include "dirs.h" -+#include "internal/dirs.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/json.h" - #include "openvswitch/vlog.h" --#include "ovsdb-data.h" --#include "ovsdb-idl.h" --#include "ovsdb-idl-provider.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-idl.h" -+#include "openvswitch/ovsdb-idl-provider.h" - #include "openvswitch/shash.h" --#include "sset.h" --#include "svec.h" -+#include "internal/sset.h" -+#include "internal/svec.h" - #include "string.h" --#include "table.h" --#include "util.h" -+#include "internal/table.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(db_ctl_base); - -Index: openvswitch-2.17.2/lib/dhparams.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dhparams.c -+++ openvswitch-2.17.2/lib/dhparams.c -@@ -3,7 +3,7 @@ - * If you do need to regenerate this file, run "make generate-dhparams-c". */ - - #include --#include "lib/dhparams.h" -+#include "internal/dhparams.h" - #include "openvswitch/util.h" - - static int -Index: openvswitch-2.17.2/lib/dirs.c.in -=================================================================== ---- openvswitch-2.17.2.orig/lib/dirs.c.in -+++ openvswitch-2.17.2/lib/dirs.c.in -@@ -16,10 +16,10 @@ - */ - - #include --#include "dirs.h" -+#include "internal/dirs.h" - #include --#include "ovs-thread.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/util.h" - - struct directory { - const char *value; /* Actual value; NULL if not yet determined. */ -Index: openvswitch-2.17.2/lib/dns-resolve.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dns-resolve.c -+++ openvswitch-2.17.2/lib/dns-resolve.c -@@ -24,10 +24,10 @@ - #include - #include - #include --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "openvswitch/vlog.h" --#include "timeval.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(dns_resolve); - -Index: openvswitch-2.17.2/lib/dp-packet.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dp-packet.c -+++ openvswitch-2.17.2/lib/dp-packet.c -@@ -18,11 +18,11 @@ - #include - #include - --#include "dp-packet.h" --#include "netdev-afxdp.h" --#include "netdev-dpdk.h" -+#include "internal/dp-packet.h" -+#include "internal/netdev-afxdp.h" -+#include "internal/netdev-dpdk.h" - #include "openvswitch/dynamic-string.h" --#include "util.h" -+#include "internal/util.h" - - static void - dp_packet_init__(struct dp_packet *b, size_t allocated, enum dp_packet_source source) -Index: openvswitch-2.17.2/lib/dpctl.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpctl.c -+++ openvswitch-2.17.2/lib/dpctl.c -@@ -27,27 +27,28 @@ - #include - #include - -+#include "internal/command-line.h" - #include "openvswitch/compiler.h" - #include "ct-dpif.h" --#include "dirs.h" -+#include "internal/dirs.h" - #include "dpctl.h" - #include "dpif.h" - #include "dpif-provider.h" - #include "openvswitch/dynamic-string.h" --#include "flow.h" -+#include "internal/flow.h" - #include "openvswitch/match.h" --#include "netdev.h" --#include "netlink.h" -+#include "internal/netdev.h" -+#include "internal/netlink.h" - #include "odp-util.h" - #include "openvswitch/ofpbuf.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/shash.h" --#include "simap.h" --#include "smap.h" --#include "sset.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/simap.h" -+#include "internal/smap.h" -+#include "internal/sset.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/ofp-flow.h" - #include "openvswitch/ofp-port.h" - -Index: openvswitch-2.17.2/lib/dpdk-stub.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpdk-stub.c -+++ openvswitch-2.17.2/lib/dpdk-stub.c -@@ -18,8 +18,8 @@ - #include - #include "dpdk.h" - --#include "smap.h" --#include "ovs-thread.h" -+#include "internal/smap.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/vlog.h" - #include "vswitch-idl.h" - -Index: openvswitch-2.17.2/lib/dpdk.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpdk.c -+++ openvswitch-2.17.2/lib/dpdk.c -@@ -29,18 +29,18 @@ - #include - #include - --#include "dirs.h" --#include "fatal-signal.h" --#include "netdev-dpdk.h" -+#include "internal/dirs.h" -+#include "internal/fatal-signal.h" -+#include "internal/netdev-dpdk.h" - #include "netdev-offload-provider.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/vlog.h" --#include "ovs-atomic.h" --#include "ovs-numa.h" --#include "smap.h" --#include "svec.h" --#include "unixctl.h" --#include "util.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-numa.h" -+#include "internal/smap.h" -+#include "internal/svec.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "vswitch-idl.h" - - VLOG_DEFINE_THIS_MODULE(dpdk); -Index: openvswitch-2.17.2/lib/dpif-netdev-avx512.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-avx512.c -+++ openvswitch-2.17.2/lib/dpif-netdev-avx512.c -@@ -28,8 +28,8 @@ - #include - #include - --#include "dp-packet.h" --#include "netdev.h" -+#include "internal/dp-packet.h" -+#include "internal/netdev.h" - #include "netdev-offload.h" - - /* Each AVX512 register (zmm register in assembly notation) can contain up to -Index: openvswitch-2.17.2/lib/dpif-netdev-extract-avx512.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-extract-avx512.c -+++ openvswitch-2.17.2/lib/dpif-netdev-extract-avx512.c -@@ -43,7 +43,7 @@ - #include - - #include "cpu.h" --#include "flow.h" -+#include "internal/flow.h" - - #include "dpif-netdev-private-dpcls.h" - #include "dpif-netdev-private-extract.h" -Index: openvswitch-2.17.2/lib/dpif-netdev-extract-study.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-extract-study.c -+++ openvswitch-2.17.2/lib/dpif-netdev-extract-study.c -@@ -21,7 +21,7 @@ - - #include "dpif-netdev-private-thread.h" - #include "openvswitch/vlog.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - - VLOG_DEFINE_THIS_MODULE(dpif_mfex_extract_study); - -Index: openvswitch-2.17.2/lib/dpif-netdev-lookup-avx512-gather.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup-avx512-gather.c -+++ openvswitch-2.17.2/lib/dpif-netdev-lookup-avx512-gather.c -@@ -22,10 +22,10 @@ - #include "dpif-netdev.h" - #include "dpif-netdev-lookup.h" - --#include "cmap.h" -+#include "internal/cmap.h" - #include "cpu.h" --#include "flow.h" --#include "pvector.h" -+#include "internal/flow.h" -+#include "internal/pvector.h" - #include "openvswitch/vlog.h" - - #include "immintrin.h" -Index: openvswitch-2.17.2/lib/dpif-netdev-lookup-generic.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup-generic.c -+++ openvswitch-2.17.2/lib/dpif-netdev-lookup-generic.c -@@ -19,17 +19,17 @@ - #include "dpif-netdev.h" - #include "dpif-netdev-lookup.h" - --#include "bitmap.h" --#include "cmap.h" -+#include "internal/bitmap.h" -+#include "internal/cmap.h" - --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "dpif.h" - #include "dpif-netdev-perf.h" - #include "dpif-provider.h" --#include "flow.h" --#include "ovs-thread.h" --#include "packets.h" --#include "pvector.h" -+#include "internal/flow.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/pvector.h" - - VLOG_DEFINE_THIS_MODULE(dpif_lookup_generic); - -Index: openvswitch-2.17.2/lib/dpif-netdev-perf.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-perf.c -+++ openvswitch-2.17.2/lib/dpif-netdev-perf.c -@@ -21,9 +21,9 @@ - #include "dpif-netdev-perf.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/vlog.h" --#include "ovs-numa.h" --#include "ovs-thread.h" --#include "timeval.h" -+#include "openvswitch/ovs-numa.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(pmd_perf); - -Index: openvswitch-2.17.2/lib/dpif-netdev-perf.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-perf.h -+++ openvswitch-2.17.2/lib/dpif-netdev-perf.h -@@ -30,10 +30,10 @@ - #endif - - #include "openvswitch/vlog.h" --#include "ovs-atomic.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/dpif-netdev-private-dpcls.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-dpcls.h -+++ openvswitch-2.17.2/lib/dpif-netdev-private-dpcls.h -@@ -23,7 +23,7 @@ - #include - #include - --#include "cmap.h" -+#include "internal/cmap.h" - #include "openvswitch/thread.h" - - #ifdef __cplusplus -Index: openvswitch-2.17.2/lib/dpif-netdev-private-dpif.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-dpif.c -+++ openvswitch-2.17.2/lib/dpif-netdev-private-dpif.c -@@ -24,7 +24,7 @@ - - #include "openvswitch/dynamic-string.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(dpif_netdev_impl); - -Index: openvswitch-2.17.2/lib/dpif-netdev-private-extract.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-extract.c -+++ openvswitch-2.17.2/lib/dpif-netdev-private-extract.c -@@ -19,14 +19,14 @@ - #include - #include - --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "dpif-netdev-private-dpcls.h" - #include "dpif-netdev-private-extract.h" - #include "dpif-netdev-private-thread.h" --#include "flow.h" -+#include "internal/flow.h" - #include "openvswitch/vlog.h" --#include "ovs-thread.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(dpif_netdev_extract); - -Index: openvswitch-2.17.2/lib/dpif-netdev-private-flow.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-flow.h -+++ openvswitch-2.17.2/lib/dpif-netdev-private-flow.h -@@ -24,7 +24,7 @@ - #include - #include - --#include "cmap.h" -+#include "internal/cmap.h" - #include "openvswitch/thread.h" - - #ifdef __cplusplus -Index: openvswitch-2.17.2/lib/dpif-netdev-private-thread.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-thread.h -+++ openvswitch-2.17.2/lib/dpif-netdev-private-thread.h -@@ -27,7 +27,7 @@ - #include - - #include "ccmap.h" --#include "cmap.h" -+#include "internal/cmap.h" - - #include "dpif-netdev-private-dfc.h" - #include "dpif-netdev-private-dpif.h" -Index: openvswitch-2.17.2/lib/dpif-netdev.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev.c -+++ openvswitch-2.17.2/lib/dpif-netdev.c -@@ -34,15 +34,15 @@ - #include - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "ccmap.h" --#include "cmap.h" -+#include "internal/cmap.h" - #include "conntrack.h" - #include "conntrack-tp.h" --#include "coverage.h" -+#include "internal/coverage.h" - #include "ct-dpif.h" --#include "csum.h" --#include "dp-packet.h" -+#include "internal/csum.h" -+#include "internal/dp-packet.h" - #include "dpif.h" - #include "dpif-netdev-lookup.h" - #include "dpif-netdev-perf.h" -@@ -50,18 +50,18 @@ - #include "dpif-provider.h" - #include "dummy.h" - #include "fat-rwlock.h" --#include "flow.h" --#include "hmapx.h" -+#include "internal/flow.h" -+#include "internal/hmapx.h" - #include "id-fpool.h" --#include "id-pool.h" -+#include "internal/id-pool.h" - #include "ipf.h" - #include "mov-avg.h" - #include "mpsc-queue.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "netdev-offload.h" - #include "netdev-provider.h" - #include "netdev-vport.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "odp-execute.h" - #include "odp-util.h" - #include "openvswitch/dynamic-string.h" -@@ -72,21 +72,21 @@ - #include "openvswitch/ofpbuf.h" - #include "openvswitch/shash.h" - #include "openvswitch/vlog.h" --#include "ovs-numa.h" --#include "ovs-rcu.h" --#include "packets.h" -+#include "openvswitch/ovs-numa.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "pvector.h" --#include "random.h" --#include "seq.h" --#include "smap.h" --#include "sset.h" --#include "timeval.h" -+#include "internal/pvector.h" -+#include "internal/random.h" -+#include "internal/seq.h" -+#include "internal/smap.h" -+#include "internal/sset.h" -+#include "internal/timeval.h" - #include "tnl-neigh-cache.h" - #include "tnl-ports.h" --#include "unixctl.h" --#include "util.h" --#include "uuid.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(dpif_netdev); - -Index: openvswitch-2.17.2/lib/dpif-netdev.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev.h -+++ openvswitch-2.17.2/lib/dpif-netdev.h -@@ -22,8 +22,8 @@ - #include - #include "dpif.h" - #include "openvswitch/types.h" --#include "dp-packet.h" --#include "packets.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/dpif-netlink-rtnl.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netlink-rtnl.h -+++ openvswitch-2.17.2/lib/dpif-netlink-rtnl.h -@@ -19,7 +19,7 @@ - - #include - --#include "netdev.h" -+#include "internal/netdev.h" - - /* Declare these to keep sparse happy. */ - int dpif_netlink_rtnl_port_create(struct netdev *netdev); -Index: openvswitch-2.17.2/lib/dpif-netlink.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netlink.c -+++ openvswitch-2.17.2/lib/dpif-netlink.c -@@ -32,20 +32,20 @@ - #include - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "dpif-netlink-rtnl.h" - #include "dpif-provider.h" - #include "fat-rwlock.h" --#include "flow.h" -+#include "internal/flow.h" - #include "netdev-linux.h" - #include "netdev-offload.h" - #include "netdev-provider.h" - #include "netdev-vport.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "netlink-conntrack.h" - #include "netlink-notifier.h" - #include "netlink-socket.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "netnsid.h" - #include "odp-util.h" - #include "openvswitch/dynamic-string.h" -@@ -58,12 +58,12 @@ - #include "openvswitch/thread.h" - #include "openvswitch/usdt-probes.h" - #include "openvswitch/vlog.h" --#include "packets.h" --#include "random.h" --#include "sset.h" --#include "timeval.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/random.h" -+#include "internal/sset.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(dpif_netlink); - #ifdef _WIN32 -Index: openvswitch-2.17.2/lib/dpif-netlink.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netlink.h -+++ openvswitch-2.17.2/lib/dpif-netlink.h -@@ -21,7 +21,7 @@ - #include - #include - --#include "flow.h" -+#include "internal/flow.h" - - struct ofpbuf; - -Index: openvswitch-2.17.2/lib/dpif-provider.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-provider.h -+++ openvswitch-2.17.2/lib/dpif-provider.h -@@ -24,7 +24,7 @@ - - #include "openflow/openflow.h" - #include "dpif.h" --#include "util.h" -+#include "internal/util.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/dpif.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif.c -+++ openvswitch-2.17.2/lib/dpif.c -@@ -23,25 +23,25 @@ - #include - #include - --#include "coverage.h" --#include "dp-packet.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" - #include "dpctl.h" - #include "dpif-netdev.h" --#include "flow.h" -+#include "internal/flow.h" - #include "netdev-provider.h" --#include "netdev.h" --#include "netlink.h" -+#include "internal/netdev.h" -+#include "internal/netlink.h" - #include "odp-execute.h" - #include "odp-util.h" --#include "packets.h" -+#include "internal/packets.h" - #include "route-table.h" --#include "seq.h" --#include "sset.h" --#include "timeval.h" -+#include "internal/seq.h" -+#include "internal/sset.h" -+#include "internal/timeval.h" - #include "tnl-neigh-cache.h" - #include "tnl-ports.h" --#include "util.h" --#include "uuid.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - #include "valgrind.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/ofp-errors.h" -Index: openvswitch-2.17.2/lib/dpif.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif.h -+++ openvswitch-2.17.2/lib/dpif.h -@@ -377,13 +377,13 @@ - #include - - #include "dpdk.h" --#include "dp-packet.h" --#include "netdev.h" -+#include "internal/dp-packet.h" -+#include "internal/netdev.h" - #include "openflow/openflow.h" - #include "openvswitch/ofp-meter.h" --#include "ovs-numa.h" --#include "packets.h" --#include "util.h" -+#include "openvswitch/ovs-numa.h" -+#include "internal/packets.h" -+#include "internal/util.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/dummy.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dummy.c -+++ openvswitch-2.17.2/lib/dummy.c -@@ -17,7 +17,7 @@ - #include - #include "dummy.h" - #include --#include "util.h" -+#include "internal/util.h" - - /* Enables support for "dummy" network devices and dpifs, which are useful for - * testing. A client program might call this function if it is designed -Index: openvswitch-2.17.2/lib/dynamic-string.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dynamic-string.c -+++ openvswitch-2.17.2/lib/dynamic-string.c -@@ -20,8 +20,8 @@ - #include - #include - #include --#include "timeval.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - /* Initializes 'ds' as an empty string buffer. */ - void -Index: openvswitch-2.17.2/lib/entropy.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/entropy.c -+++ openvswitch-2.17.2/lib/entropy.c -@@ -23,8 +23,8 @@ - #ifdef _WIN32 - #include - #endif --#include "util.h" --#include "socket-util.h" -+#include "internal/util.h" -+#include "internal/socket-util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(entropy); -Index: openvswitch-2.17.2/lib/fat-rwlock.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/fat-rwlock.c -+++ openvswitch-2.17.2/lib/fat-rwlock.c -@@ -22,8 +22,8 @@ - - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" --#include "random.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/random.h" - - struct fat_rwlock_slot { - /* Membership in rwlock's list of "struct fat_rwlock_slot"s. -Index: openvswitch-2.17.2/lib/fat-rwlock.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/fat-rwlock.h -+++ openvswitch-2.17.2/lib/fat-rwlock.h -@@ -19,7 +19,7 @@ - - #include "openvswitch/compiler.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - - /* "Fat rwlock". - * -Index: openvswitch-2.17.2/lib/fatal-signal.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/fatal-signal.c -+++ openvswitch-2.17.2/lib/fatal-signal.c -@@ -15,7 +15,7 @@ - */ - #include - #include "backtrace.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include - #include - #include -@@ -24,13 +24,13 @@ - #include - #include - #include --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "sset.h" -+#include "internal/sset.h" - #include "signals.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - #include "openvswitch/type-props.h" -Index: openvswitch-2.17.2/lib/flow.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/flow.c -+++ openvswitch-2.17.2/lib/flow.c -@@ -15,7 +15,7 @@ - */ - #include - #include --#include "flow.h" -+#include "internal/flow.h" - #include - #include - #include -@@ -26,21 +26,21 @@ - #include - #include - #include --#include "byte-order.h" --#include "colors.h" --#include "coverage.h" --#include "csum.h" -+#include "internal/byte-order.h" -+#include "internal/colors.h" -+#include "internal/coverage.h" -+#include "internal/csum.h" - #include "openvswitch/dynamic-string.h" --#include "hash.h" -+#include "internal/hash.h" - #include "jhash.h" - #include "openvswitch/match.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openflow/openflow.h" --#include "packets.h" -+#include "internal/packets.h" - #include "odp-util.h" --#include "random.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "openvswitch/nsh.h" - #include "ovs-router.h" - #include "lib/netdev-provider.h" -@@ -133,7 +133,7 @@ struct mf_ctx { - /* miniflow_push_* macros allow filling in a miniflow data values in order. - * Assertions are needed only when the layout of the struct flow is modified. - * 'ofs' is a compile-time constant, which allows most of the code be optimized -- * away. Some GCC versions gave warnings on ALWAYS_INLINE, so these are -+ * away. Some GCC versions gave warnings on OVS_ALWAYS_INLINE, so these are - * defined as macros. */ - - #if (FLOW_WC_SEQ != 42) -@@ -345,7 +345,7 @@ parse_mpls(const void **datap, size_t *s - } - - /* passed vlan_hdrs arg must be at least size FLOW_MAX_VLAN_HEADERS. */ --static inline ALWAYS_INLINE size_t -+static inline OVS_ALWAYS_INLINE size_t - parse_vlan(const void **datap, size_t *sizep, union flow_vlan_hdr *vlan_hdrs) - { - const ovs_be16 *eth_type; -@@ -369,7 +369,7 @@ parse_vlan(const void **datap, size_t *s - return n; - } - --static inline ALWAYS_INLINE ovs_be16 -+static inline OVS_ALWAYS_INLINE ovs_be16 - parse_ethertype(const void **datap, size_t *sizep) - { - const struct llc_snap_header *llc; -Index: openvswitch-2.17.2/lib/getopt_long.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/getopt_long.c -+++ openvswitch-2.17.2/lib/getopt_long.c -@@ -32,7 +32,7 @@ - #include - #include - #include --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(getopt_long); -Index: openvswitch-2.17.2/lib/getrusage-windows.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/getrusage-windows.c -+++ openvswitch-2.17.2/lib/getrusage-windows.c -@@ -19,7 +19,7 @@ - #include - #include - #include --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(getrusage_windows); -Index: openvswitch-2.17.2/lib/guarded-list.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/guarded-list.h -+++ openvswitch-2.17.2/lib/guarded-list.h -@@ -20,7 +20,7 @@ - #include - #include "openvswitch/compiler.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - - struct guarded_list { - struct ovs_mutex mutex; -Index: openvswitch-2.17.2/lib/hash.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/hash.c -+++ openvswitch-2.17.2/lib/hash.c -@@ -14,9 +14,9 @@ - * limitations under the License. - */ - #include --#include "hash.h" -+#include "internal/hash.h" - #include --#include "unaligned.h" -+#include "internal/unaligned.h" - - /* Returns the hash of 'a', 'b', and 'c'. */ - uint32_t -Index: openvswitch-2.17.2/lib/heap.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/heap.c -+++ openvswitch-2.17.2/lib/heap.c -@@ -17,7 +17,7 @@ - #include - #include "heap.h" - #include --#include "util.h" -+#include "internal/util.h" - - static void put_node(struct heap *, struct heap_node *, size_t i); - static void swap_nodes(struct heap *, size_t i, size_t j); -Index: openvswitch-2.17.2/lib/hindex.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/hindex.c -+++ openvswitch-2.17.2/lib/hindex.c -@@ -15,8 +15,8 @@ - */ - - #include --#include "hindex.h" --#include "coverage.h" -+#include "internal/hindex.h" -+#include "internal/coverage.h" - - static bool hindex_node_is_body(const struct hindex_node *); - static bool hindex_node_is_head(const struct hindex_node *); -Index: openvswitch-2.17.2/lib/hmap.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/hmap.c -+++ openvswitch-2.17.2/lib/hmap.c -@@ -18,9 +18,9 @@ - #include "openvswitch/hmap.h" - #include - #include --#include "coverage.h" --#include "random.h" --#include "util.h" -+#include "internal/coverage.h" -+#include "internal/random.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(hmap); -Index: openvswitch-2.17.2/lib/hmapx.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/hmapx.c -+++ openvswitch-2.17.2/lib/hmapx.c -@@ -16,9 +16,9 @@ - - #include - --#include "hmapx.h" -+#include "internal/hmapx.h" - --#include "hash.h" -+#include "internal/hash.h" - - static struct hmapx_node * - hmapx_find__(const struct hmapx *map, const void *data, size_t hash) -Index: openvswitch-2.17.2/lib/id-fpool.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/id-fpool.c -+++ openvswitch-2.17.2/lib/id-fpool.c -@@ -19,7 +19,7 @@ - #include "openvswitch/list.h" - #include "openvswitch/thread.h" - #include "openvswitch/util.h" --#include "ovs-atomic.h" -+#include "openvswitch/ovs-atomic.h" - #include "id-fpool.h" - - #ifdef HAVE_PTHREAD_SPIN_LOCK -Index: openvswitch-2.17.2/lib/id-pool.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/id-pool.c -+++ openvswitch-2.17.2/lib/id-pool.c -@@ -16,9 +16,9 @@ - */ - - #include --#include "id-pool.h" -+#include "internal/id-pool.h" - #include "openvswitch/hmap.h" --#include "hash.h" -+#include "internal/hash.h" - - struct id_node { - struct hmap_node node; -Index: openvswitch-2.17.2/lib/if-notifier-bsd.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/if-notifier-bsd.c -+++ openvswitch-2.17.2/lib/if-notifier-bsd.c -@@ -17,7 +17,7 @@ - #include - #include "if-notifier.h" - #include "rtbsd.h" --#include "util.h" -+#include "internal/util.h" - - struct if_notifier { - struct rtbsd_notifier notifier; -Index: openvswitch-2.17.2/lib/if-notifier.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/if-notifier.c -+++ openvswitch-2.17.2/lib/if-notifier.c -@@ -17,7 +17,7 @@ - #include - #include "if-notifier.h" - #include "rtnetlink.h" --#include "util.h" -+#include "internal/util.h" - - struct if_notifier { - struct nln_notifier *notifier; -Index: openvswitch-2.17.2/lib/ipf.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ipf.c -+++ openvswitch-2.17.2/lib/ipf.c -@@ -23,16 +23,16 @@ - #include - #include - --#include "coverage.h" --#include "csum.h" -+#include "internal/coverage.h" -+#include "internal/csum.h" - #include "ipf.h" --#include "latch.h" -+#include "internal/latch.h" - #include "openvswitch/hmap.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" --#include "ovs-atomic.h" --#include "packets.h" --#include "util.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/packets.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ipf); - COVERAGE_DEFINE(ipf_stuck_frag_list_purged); -Index: openvswitch-2.17.2/lib/ipf.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ipf.h -+++ openvswitch-2.17.2/lib/ipf.h -@@ -17,7 +17,7 @@ - #ifndef IPF_H - #define IPF_H 1 - --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/types.h" - - struct ipf; -Index: openvswitch-2.17.2/lib/jhash.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/jhash.c -+++ openvswitch-2.17.2/lib/jhash.c -@@ -17,7 +17,7 @@ - #include - #include "jhash.h" - #include --#include "unaligned.h" -+#include "internal/unaligned.h" - - /* This is the public domain lookup3 hash by Bob Jenkins from - * http://burtleburtle.net/bob/c/lookup3.c, modified for style. */ -Index: openvswitch-2.17.2/lib/jhash.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/jhash.h -+++ openvswitch-2.17.2/lib/jhash.h -@@ -21,7 +21,7 @@ - #include - #include - #include --#include "util.h" -+#include "internal/util.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/json.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/json.c -+++ openvswitch-2.17.2/lib/json.c -@@ -25,11 +25,11 @@ - #include - - #include "openvswitch/dynamic-string.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/shash.h" - #include "unicode.h" --#include "util.h" --#include "uuid.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - /* The type of a JSON token. */ - enum json_token_type { -Index: openvswitch-2.17.2/lib/jsonrpc.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/jsonrpc.c -+++ openvswitch-2.17.2/lib/jsonrpc.c -@@ -16,23 +16,23 @@ - - #include - --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - - #include - - #include "byteq.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/json.h" - #include "openvswitch/list.h" - #include "openvswitch/ofpbuf.h" - #include "ovs-replay.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" - #include "reconnect.h" --#include "stream.h" --#include "svec.h" --#include "timeval.h" -+#include "internal/stream.h" -+#include "internal/svec.h" -+#include "internal/timeval.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(jsonrpc); -Index: openvswitch-2.17.2/lib/lacp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/lacp.c -+++ openvswitch-2.17.2/lib/lacp.c -@@ -20,19 +20,19 @@ - - #include "connectivity.h" - #include "openvswitch/dynamic-string.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "dp-packet.h" --#include "ovs-atomic.h" --#include "packets.h" -+#include "internal/dp-packet.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" -+#include "internal/seq.h" - #include "openvswitch/shash.h" --#include "timer.h" --#include "timeval.h" --#include "unixctl.h" -+#include "internal/timer.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(lacp); - -Index: openvswitch-2.17.2/lib/lacp.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/lacp.h -+++ openvswitch-2.17.2/lib/lacp.h -@@ -19,7 +19,7 @@ - - #include - #include --#include "packets.h" -+#include "internal/packets.h" - - /* LACP Protocol Implementation. */ - -Index: openvswitch-2.17.2/lib/latch-unix.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/latch-unix.c -+++ openvswitch-2.17.2/lib/latch-unix.c -@@ -16,12 +16,12 @@ - - #include - --#include "latch.h" -+#include "internal/latch.h" - #include - #include - #include - #include "openvswitch/poll-loop.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - - /* Initializes 'latch' as initially unset. */ - void -Index: openvswitch-2.17.2/lib/latch-windows.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/latch-windows.c -+++ openvswitch-2.17.2/lib/latch-windows.c -@@ -16,12 +16,12 @@ - - #include - --#include "latch.h" -+#include "internal/latch.h" - #include - #include - #include - #include "openvswitch/poll-loop.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - - /* Initializes 'latch' as initially unset. */ - void -Index: openvswitch-2.17.2/lib/learn.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/learn.c -+++ openvswitch-2.17.2/lib/learn.c -@@ -18,9 +18,9 @@ - - #include "learn.h" - --#include "byte-order.h" --#include "colors.h" --#include "nx-match.h" -+#include "internal/byte-order.h" -+#include "internal/colors.h" -+#include "internal/nx-match.h" - #include "openflow/openflow.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/match.h" -@@ -32,7 +32,7 @@ - #include "openvswitch/ofp-table.h" - #include "openvswitch/ofpbuf.h" - #include "vl-mff-map.h" --#include "unaligned.h" -+#include "internal/unaligned.h" - - - /* Checks that 'learn' is a valid action on 'flow'. Returns 0 if it is valid, -Index: openvswitch-2.17.2/lib/learning-switch.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/learning-switch.c -+++ openvswitch-2.17.2/lib/learning-switch.c -@@ -24,10 +24,10 @@ - #include - #include - --#include "byte-order.h" --#include "classifier.h" --#include "dp-packet.h" --#include "flow.h" -+#include "internal/byte-order.h" -+#include "internal/classifier.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" - #include "openvswitch/hmap.h" - #include "mac-learning.h" - #include "openflow/openflow.h" -@@ -48,8 +48,8 @@ - #include "openvswitch/poll-loop.h" - #include "openvswitch/rconn.h" - #include "openvswitch/shash.h" --#include "simap.h" --#include "timeval.h" -+#include "internal/simap.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(learning_switch); - -Index: openvswitch-2.17.2/lib/lldp/lldp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/lldp/lldp.c -+++ openvswitch-2.17.2/lib/lldp/lldp.c -@@ -26,8 +26,8 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "dp-packet.h" --#include "packets.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" - - VLOG_DEFINE_THIS_MODULE(lldp); - -Index: openvswitch-2.17.2/lib/lldp/lldpd-structs.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/lldp/lldpd-structs.c -+++ openvswitch-2.17.2/lib/lldp/lldpd-structs.c -@@ -21,7 +21,7 @@ - #include - #include - #include "lldpd.h" --#include "timeval.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(lldpd_structs); - -Index: openvswitch-2.17.2/lib/lldp/lldpd-structs.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/lldp/lldpd-structs.h -+++ openvswitch-2.17.2/lib/lldp/lldpd-structs.h -@@ -25,7 +25,7 @@ - #include - #include "aa-structs.h" - #include "lldp-const.h" --#include "packets.h" -+#include "internal/packets.h" - - enum { - LLDPD_AF_UNSPEC = 0, -Index: openvswitch-2.17.2/lib/lldp/lldpd.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/lldp/lldpd.c -+++ openvswitch-2.17.2/lib/lldp/lldpd.c -@@ -42,8 +42,8 @@ - #include "openvswitch/compiler.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/list.h" --#include "packets.h" --#include "timeval.h" -+#include "internal/packets.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(lldpd); - -Index: openvswitch-2.17.2/lib/lldp/lldpd.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/lldp/lldpd.h -+++ openvswitch-2.17.2/lib/lldp/lldpd.h -@@ -24,11 +24,11 @@ - #include - #include - #include --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/list.h" - #include "lldpd-structs.h" - #include "lldp-tlv.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/vlog.h" - - #define ETHERTYPE_LLDP 0x88cc -Index: openvswitch-2.17.2/lib/lockfile.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/lockfile.c -+++ openvswitch-2.17.2/lib/lockfile.c -@@ -24,12 +24,12 @@ - #include - #include - --#include "coverage.h" --#include "hash.h" -+#include "internal/coverage.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "ovs-thread.h" --#include "timeval.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(lockfile); -Index: openvswitch-2.17.2/lib/mac-learning.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/mac-learning.c -+++ openvswitch-2.17.2/lib/mac-learning.c -@@ -20,14 +20,14 @@ - #include - #include - --#include "bitmap.h" --#include "coverage.h" --#include "hash.h" -+#include "internal/bitmap.h" -+#include "internal/coverage.h" -+#include "internal/hash.h" - #include "openvswitch/list.h" - #include "openvswitch/poll-loop.h" --#include "timeval.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "vlan-bitmap.h" - - COVERAGE_DEFINE(mac_learning_learned); -Index: openvswitch-2.17.2/lib/mac-learning.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/mac-learning.h -+++ openvswitch-2.17.2/lib/mac-learning.h -@@ -21,10 +21,10 @@ - #include "heap.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" --#include "ovs-atomic.h" --#include "ovs-thread.h" --#include "packets.h" --#include "timeval.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/timeval.h" - - /* MAC learning table - * ================== -Index: openvswitch-2.17.2/lib/match.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/match.c -+++ openvswitch-2.17.2/lib/match.c -@@ -17,14 +17,14 @@ - #include - #include "openvswitch/match.h" - #include --#include "flow.h" --#include "byte-order.h" --#include "colors.h" -+#include "internal/flow.h" -+#include "internal/byte-order.h" -+#include "internal/colors.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/meta-flow.h" - #include "openvswitch/ofp-port.h" --#include "packets.h" --#include "tun-metadata.h" -+#include "internal/packets.h" -+#include "internal/tun-metadata-private.h" - #include "openvswitch/nsh.h" - - /* Converts the flow in 'flow' into a match in 'match', with the given -Index: openvswitch-2.17.2/lib/mcast-snooping.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/mcast-snooping.c -+++ openvswitch-2.17.2/lib/mcast-snooping.c -@@ -17,21 +17,21 @@ - */ - - #include --#include "mcast-snooping.h" -+#include "internal/mcast-snooping.h" - - #include - #include - --#include "bitmap.h" --#include "byte-order.h" --#include "coverage.h" --#include "hash.h" -+#include "internal/bitmap.h" -+#include "internal/byte-order.h" -+#include "internal/coverage.h" -+#include "internal/hash.h" - #include "openvswitch/list.h" - #include "openvswitch/poll-loop.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "entropy.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "vlan-bitmap.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/lib/memory.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/memory.c -+++ openvswitch-2.17.2/lib/memory.c -@@ -15,15 +15,15 @@ - */ - - #include --#include "memory.h" -+#include "internal/memory.h" - #include - #include - #include - #include "openvswitch/dynamic-string.h" - #include "openvswitch/poll-loop.h" --#include "simap.h" --#include "timeval.h" --#include "unixctl.h" -+#include "internal/simap.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(memory); -Index: openvswitch-2.17.2/lib/meta-flow.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/meta-flow.c -+++ openvswitch-2.17.2/lib/meta-flow.c -@@ -23,19 +23,19 @@ - #include - #include - --#include "classifier.h" -+#include "internal/classifier.h" - #include "openvswitch/dynamic-string.h" --#include "nx-match.h" --#include "ovs-atomic.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" --#include "packets.h" --#include "random.h" -+#include "internal/nx-match.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/random.h" - #include "openvswitch/shash.h" --#include "socket-util.h" --#include "tun-metadata.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-match.h" - #include "openvswitch/ofp-port.h" -Index: openvswitch-2.17.2/lib/mpsc-queue.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/mpsc-queue.c -+++ openvswitch-2.17.2/lib/mpsc-queue.c -@@ -16,7 +16,7 @@ - - #include - --#include "ovs-atomic.h" -+#include "openvswitch/ovs-atomic.h" - - #include "mpsc-queue.h" - -Index: openvswitch-2.17.2/lib/mpsc-queue.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/mpsc-queue.h -+++ openvswitch-2.17.2/lib/mpsc-queue.h -@@ -24,7 +24,7 @@ - #include - #include - --#include "ovs-atomic.h" -+#include "openvswitch/ovs-atomic.h" - - /* Multi-producer, single-consumer queue - * ===================================== -Index: openvswitch-2.17.2/lib/multipath.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/multipath.c -+++ openvswitch-2.17.2/lib/multipath.c -@@ -21,14 +21,14 @@ - #include - #include - #include --#include "colors.h" --#include "nx-match.h" -+#include "internal/colors.h" -+#include "internal/nx-match.h" - #include "openflow/nicira-ext.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofp-errors.h" --#include "packets.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/util.h" - - /* Checks that 'mp' is valid on flow. Returns 0 if it is valid, otherwise an - * OFPERR_*. */ -Index: openvswitch-2.17.2/lib/namemap.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/namemap.c -+++ openvswitch-2.17.2/lib/namemap.c -@@ -17,7 +17,7 @@ - #include - #include "openvswitch/namemap.h" - #include --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" - -Index: openvswitch-2.17.2/lib/netdev-afxdp-pool.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-afxdp-pool.c -+++ openvswitch-2.17.2/lib/netdev-afxdp-pool.c -@@ -15,7 +15,7 @@ - */ - #include - --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "netdev-afxdp-pool.h" - #include "openvswitch/util.h" - -Index: openvswitch-2.17.2/lib/netdev-afxdp-pool.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-afxdp-pool.h -+++ openvswitch-2.17.2/lib/netdev-afxdp-pool.h -@@ -24,7 +24,7 @@ - #include - - #include "openvswitch/thread.h" --#include "ovs-atomic.h" -+#include "openvswitch/ovs-atomic.h" - - /* LIFO ptr_array. */ - struct umem_pool { -Index: openvswitch-2.17.2/lib/netdev-afxdp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-afxdp.c -+++ openvswitch-2.17.2/lib/netdev-afxdp.c -@@ -18,7 +18,7 @@ - - #include "netdev-linux-private.h" - #include "netdev-linux.h" --#include "netdev-afxdp.h" -+#include "internal/netdev-afxdp.h" - #include "netdev-afxdp-pool.h" - - #include -@@ -35,19 +35,19 @@ - #include - #include - --#include "coverage.h" --#include "dp-packet.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" - #include "dpif-netdev.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/compiler.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/list.h" - #include "openvswitch/thread.h" - #include "openvswitch/vlog.h" --#include "ovs-numa.h" --#include "packets.h" --#include "socket-util.h" --#include "util.h" -+#include "openvswitch/ovs-numa.h" -+#include "internal/packets.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - - #ifndef SOL_XDP - #define SOL_XDP 283 -Index: openvswitch-2.17.2/lib/netdev-bsd.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-bsd.c -+++ openvswitch-2.17.2/lib/netdev-bsd.c -@@ -48,19 +48,19 @@ - #endif - - #include "rtbsd.h" --#include "coverage.h" --#include "dp-packet.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" - #include "dpif-netdev.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openflow/openflow.h" --#include "ovs-thread.h" --#include "packets.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "socket-util.h" --#include "svec.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/svec.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(netdev_bsd); -Index: openvswitch-2.17.2/lib/netdev-dpdk.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-dpdk.c -+++ openvswitch-2.17.2/lib/netdev-dpdk.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "netdev-dpdk.h" -+#include "internal/netdev-dpdk.h" - - #include - #include -@@ -39,13 +39,13 @@ - #include - #include - --#include "cmap.h" --#include "coverage.h" --#include "dirs.h" --#include "dp-packet.h" -+#include "internal/cmap.h" -+#include "internal/coverage.h" -+#include "internal/dirs.h" -+#include "internal/dp-packet.h" - #include "dpdk.h" - #include "dpif-netdev.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "if-notifier.h" - #include "netdev-provider.h" - #include "netdev-vport.h" -@@ -56,18 +56,18 @@ - #include "openvswitch/ofp-print.h" - #include "openvswitch/shash.h" - #include "openvswitch/vlog.h" --#include "ovs-numa.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" --#include "packets.h" --#include "smap.h" --#include "sset.h" --#include "timeval.h" --#include "unaligned.h" --#include "unixctl.h" -+#include "openvswitch/ovs-numa.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/smap.h" -+#include "internal/sset.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" - #include "userspace-tso.h" --#include "util.h" --#include "uuid.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM}; - -Index: openvswitch-2.17.2/lib/netdev-dummy.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-dummy.c -+++ openvswitch-2.17.2/lib/netdev-dummy.c -@@ -21,9 +21,9 @@ - #include - #include - --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "dpif-netdev.h" --#include "flow.h" -+#include "internal/flow.h" - #include "netdev-offload-provider.h" - #include "netdev-provider.h" - #include "netdev-vport.h" -@@ -34,16 +34,16 @@ - #include "openvswitch/ofp-print.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "ovs-atomic.h" --#include "packets.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/packets.h" - #include "pcap-file.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "sset.h" --#include "stream.h" --#include "unaligned.h" --#include "timeval.h" --#include "unixctl.h" -+#include "internal/sset.h" -+#include "internal/stream.h" -+#include "internal/unaligned.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" - #include "reconnect.h" - - VLOG_DEFINE_THIS_MODULE(netdev_dummy); -Index: openvswitch-2.17.2/lib/netdev-linux-private.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-linux-private.h -+++ openvswitch-2.17.2/lib/netdev-linux-private.h -@@ -27,14 +27,14 @@ - #include - #include - --#include "dp-packet.h" --#include "netdev-afxdp.h" -+#include "internal/dp-packet.h" -+#include "internal/netdev-afxdp.h" - #include "netdev-afxdp-pool.h" - #include "netdev-provider.h" - #include "netdev-vport.h" - #include "openvswitch/thread.h" --#include "ovs-atomic.h" --#include "timer.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/timer.h" - - struct netdev; - -Index: openvswitch-2.17.2/lib/netdev-linux.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-linux.c -+++ openvswitch-2.17.2/lib/netdev-linux.c -@@ -49,37 +49,37 @@ - #include - #include - --#include "coverage.h" --#include "dp-packet.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" - #include "dpif-netlink.h" - #include "dpif-netdev.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "netdev-afxdp.h" -+#include "internal/netdev-afxdp.h" - #include "netdev-provider.h" - #include "netdev-vport.h" - #include "netlink-notifier.h" - #include "netlink-socket.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "netnsid.h" - #include "openvswitch/ofpbuf.h" - #include "openflow/openflow.h" --#include "ovs-atomic.h" --#include "ovs-numa.h" --#include "packets.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-numa.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" - #include "rtnetlink.h" - #include "openvswitch/shash.h" --#include "socket-util.h" --#include "sset.h" -+#include "internal/socket-util.h" -+#include "internal/sset.h" - #include "tc.h" --#include "timer.h" --#include "unaligned.h" -+#include "internal/timer.h" -+#include "internal/unaligned.h" - #include "openvswitch/vlog.h" - #include "userspace-tso.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(netdev_linux); - -Index: openvswitch-2.17.2/lib/netdev-native-tnl.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-native-tnl.c -+++ openvswitch-2.17.2/lib/netdev-native-tnl.c -@@ -32,17 +32,17 @@ - #include - #include - --#include "byte-order.h" --#include "csum.h" --#include "dp-packet.h" --#include "netdev.h" -+#include "internal/byte-order.h" -+#include "internal/csum.h" -+#include "internal/dp-packet.h" -+#include "internal/netdev.h" - #include "netdev-vport.h" - #include "netdev-vport-private.h" - #include "odp-netlink.h" --#include "packets.h" --#include "seq.h" --#include "unaligned.h" --#include "unixctl.h" -+#include "internal/packets.h" -+#include "internal/seq.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(native_tnl); -Index: openvswitch-2.17.2/lib/netdev-native-tnl.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-native-tnl.h -+++ openvswitch-2.17.2/lib/netdev-native-tnl.h -@@ -20,9 +20,9 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "dp-packet.h" --#include "packets.h" --#include "unixctl.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" -+#include "internal/unixctl.h" - - struct netdev; - struct ovs_action_push_tnl; -Index: openvswitch-2.17.2/lib/netdev-offload-dpdk.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-offload-dpdk.c -+++ openvswitch-2.17.2/lib/netdev-offload-dpdk.c -@@ -21,7 +21,7 @@ - #include - #include - --#include "cmap.h" -+#include "internal/cmap.h" - #include "dpif-netdev.h" - #include "netdev-offload-provider.h" - #include "netdev-provider.h" -@@ -29,9 +29,9 @@ - #include "odp-util.h" - #include "openvswitch/match.h" - #include "openvswitch/vlog.h" --#include "ovs-rcu.h" --#include "packets.h" --#include "uuid.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/packets.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(netdev_offload_dpdk); - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(600, 600); -Index: openvswitch-2.17.2/lib/netdev-offload-provider.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-offload-provider.h -+++ openvswitch-2.17.2/lib/netdev-offload-provider.h -@@ -18,11 +18,11 @@ - #ifndef NETDEV_FLOW_API_PROVIDER_H - #define NETDEV_FLOW_API_PROVIDER_H 1 - --#include "flow.h" -+#include "internal/flow.h" - #include "netdev-offload.h" - #include "openvswitch/netdev.h" - #include "openvswitch/types.h" --#include "packets.h" -+#include "internal/packets.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/netdev-offload-tc.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-offload-tc.c -+++ openvswitch-2.17.2/lib/netdev-offload-tc.c -@@ -20,7 +20,7 @@ - #include - - #include "dpif.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "openvswitch/match.h" - #include "openvswitch/ofpbuf.h" -@@ -32,13 +32,13 @@ - #include "netdev-offload-provider.h" - #include "netdev-provider.h" - #include "netdev-vport.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "netlink-socket.h" - #include "odp-netlink.h" - #include "odp-util.h" - #include "tc.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "dpif-provider.h" - - VLOG_DEFINE_THIS_MODULE(netdev_offload_tc); -Index: openvswitch-2.17.2/lib/netdev-offload.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-offload.c -+++ openvswitch-2.17.2/lib/netdev-offload.c -@@ -26,31 +26,31 @@ - #include - #include - --#include "cmap.h" --#include "coverage.h" -+#include "internal/cmap.h" -+#include "internal/coverage.h" - #include "dpif.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/list.h" - #include "netdev-offload-provider.h" - #include "netdev-provider.h" - #include "netdev-vport.h" - #include "odp-netlink.h" - #include "openflow/openflow.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/ofp-print.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" -+#include "internal/seq.h" - #include "openvswitch/shash.h" --#include "smap.h" --#include "socket-util.h" --#include "sset.h" --#include "svec.h" -+#include "internal/smap.h" -+#include "internal/socket-util.h" -+#include "internal/sset.h" -+#include "internal/svec.h" - #include "openvswitch/vlog.h" --#include "flow.h" --#include "util.h" -+#include "internal/flow.h" -+#include "internal/util.h" - #ifdef __linux__ - #include "tc.h" - #endif -Index: openvswitch-2.17.2/lib/netdev-offload.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-offload.h -+++ openvswitch-2.17.2/lib/netdev-offload.h -@@ -20,10 +20,10 @@ - - #include "openvswitch/netdev.h" - #include "openvswitch/types.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" --#include "packets.h" --#include "flow.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/flow.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/netdev-provider.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-provider.h -+++ openvswitch-2.17.2/lib/netdev-provider.h -@@ -20,15 +20,15 @@ - /* Generic interface to network devices. */ - - #include "connectivity.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "netdev-offload.h" - #include "openvswitch/list.h" --#include "ovs-numa.h" --#include "ovs-rcu.h" --#include "packets.h" --#include "seq.h" -+#include "openvswitch/ovs-numa.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/packets.h" -+#include "internal/seq.h" - #include "openvswitch/shash.h" --#include "smap.h" -+#include "internal/smap.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/netdev-vport-private.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-vport-private.h -+++ openvswitch-2.17.2/lib/netdev-vport-private.h -@@ -20,9 +20,9 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "netdev-provider.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - - struct netdev_vport { - struct netdev up; -Index: openvswitch-2.17.2/lib/netdev-vport.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-vport.c -+++ openvswitch-2.17.2/lib/netdev-vport.c -@@ -28,24 +28,24 @@ - #include - #include - --#include "byte-order.h" --#include "daemon.h" --#include "dirs.h" -+#include "internal/byte-order.h" -+#include "internal/daemon.h" -+#include "internal/dirs.h" - #include "dpif.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "netdev-native-tnl.h" - #include "netdev-provider.h" - #include "netdev-vport-private.h" - #include "openvswitch/dynamic-string.h" - #include "ovs-router.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" - #include "route-table.h" --#include "simap.h" --#include "smap.h" --#include "socket-util.h" --#include "unaligned.h" --#include "unixctl.h" -+#include "internal/simap.h" -+#include "internal/smap.h" -+#include "internal/socket-util.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" - #include "openvswitch/vlog.h" - #include "openvswitch/ofp-parse.h" - #ifdef __linux__ -Index: openvswitch-2.17.2/lib/netdev-windows.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-windows.c -+++ openvswitch-2.17.2/lib/netdev-windows.c -@@ -21,18 +21,18 @@ - - #include - --#include "coverage.h" --#include "fatal-signal.h" -+#include "internal/coverage.h" -+#include "internal/fatal-signal.h" - #include "netdev-provider.h" - #include "openvswitch/ofpbuf.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "svec.h" -+#include "internal/svec.h" - #include "openvswitch/vlog.h" - #include "odp-netlink.h" - #include "netlink-socket.h" --#include "netlink.h" -+#include "internal/netlink.h" - - VLOG_DEFINE_THIS_MODULE(netdev_windows); - static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5); -Index: openvswitch-2.17.2/lib/netdev.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev.c -+++ openvswitch-2.17.2/lib/netdev.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "netdev.h" -+#include "internal/netdev.h" - - #include - #include -@@ -31,31 +31,31 @@ - #include - #endif - --#include "cmap.h" --#include "coverage.h" -+#include "internal/cmap.h" -+#include "internal/coverage.h" - #include "dpif.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/list.h" - #include "netdev-offload-provider.h" - #include "netdev-provider.h" - #include "netdev-vport.h" - #include "odp-netlink.h" - #include "openflow/openflow.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/ofp-print.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" -+#include "internal/seq.h" - #include "openvswitch/shash.h" --#include "smap.h" --#include "socket-util.h" --#include "sset.h" --#include "svec.h" -+#include "internal/smap.h" -+#include "internal/socket-util.h" -+#include "internal/sset.h" -+#include "internal/svec.h" - #include "openvswitch/vlog.h" --#include "flow.h" --#include "util.h" -+#include "internal/flow.h" -+#include "internal/util.h" - #ifdef __linux__ - #include "tc.h" - #endif -Index: openvswitch-2.17.2/lib/netflow.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netflow.h -+++ openvswitch-2.17.2/lib/netflow.h -@@ -21,7 +21,7 @@ - - #include - #include "openvswitch/types.h" --#include "util.h" -+#include "internal/util.h" - - #define NETFLOW_V5_VERSION 5 - -Index: openvswitch-2.17.2/lib/netlink-conntrack.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink-conntrack.c -+++ openvswitch-2.17.2/lib/netlink-conntrack.c -@@ -26,17 +26,17 @@ - #include - #include - --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/compiler.h" - #include "openvswitch/dynamic-string.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "netlink-socket.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" - #include "openvswitch/poll-loop.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(netlink_conntrack); - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); -Index: openvswitch-2.17.2/lib/netlink-conntrack.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink-conntrack.h -+++ openvswitch-2.17.2/lib/netlink-conntrack.h -@@ -19,15 +19,15 @@ - - #include - --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/compiler.h" - #include "ct-dpif.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/hmap.h" - #include "openvswitch/ofpbuf.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - enum nl_ct_event_type { - NL_CT_EVENT_NEW = 1 << 0, -Index: openvswitch-2.17.2/lib/netlink-notifier.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink-notifier.c -+++ openvswitch-2.17.2/lib/netlink-notifier.c -@@ -22,8 +22,8 @@ - #include - #include - --#include "coverage.h" --#include "netlink.h" -+#include "internal/coverage.h" -+#include "internal/netlink.h" - #include "netlink-socket.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/lib/netlink-socket.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink-socket.c -+++ openvswitch-2.17.2/lib/netlink-socket.c -@@ -23,20 +23,20 @@ - #include - #include - #include --#include "coverage.h" -+#include "internal/coverage.h" - #include "openvswitch/dynamic-string.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "netlink.h" --#include "netlink-protocol.h" -+#include "internal/netlink.h" -+#include "internal/netlink-protocol.h" - #include "netnsid.h" - #include "odp-netlink.h" - #include "openvswitch/ofpbuf.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/seq.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(netlink_socket); -Index: openvswitch-2.17.2/lib/netlink-socket.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink-socket.h -+++ openvswitch-2.17.2/lib/netlink-socket.h -@@ -194,8 +194,8 @@ - #include - #include - #include "openvswitch/ofpbuf.h" --#include "ovs-atomic.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-thread.h" - - struct nl_sock; - -Index: openvswitch-2.17.2/lib/netlink.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/netlink.c -+++ openvswitch-2.17.2/lib/netlink.c -@@ -15,19 +15,19 @@ - */ - - #include --#include "netlink.h" -+#include "internal/netlink.h" - #include - #include - #include - #include --#include "coverage.h" --#include "flow.h" --#include "netlink-protocol.h" -+#include "internal/coverage.h" -+#include "internal/flow.h" -+#include "internal/netlink-protocol.h" - #include "openvswitch/ofpbuf.h" --#include "timeval.h" --#include "unaligned.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(netlink); - -Index: openvswitch-2.17.2/lib/nx-match.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/nx-match.c -+++ openvswitch-2.17.2/lib/nx-match.c -@@ -16,12 +16,12 @@ - - #include - --#include "nx-match.h" -+#include "internal/nx-match.h" - - #include - --#include "classifier.h" --#include "colors.h" -+#include "internal/classifier.h" -+#include "internal/colors.h" - #include "openvswitch/hmap.h" - #include "openflow/nicira-ext.h" - #include "openvswitch/dynamic-string.h" -@@ -32,11 +32,11 @@ - #include "openvswitch/ofp-port.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/shash.h" --#include "tun-metadata.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "vl-mff-map.h" - - VLOG_DEFINE_THIS_MODULE(nx_match); -Index: openvswitch-2.17.2/lib/object-collection.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/object-collection.c -+++ openvswitch-2.17.2/lib/object-collection.c -@@ -17,7 +17,7 @@ - #include - - #include "object-collection.h" --#include "util.h" -+#include "internal/util.h" - - void - object_collection_init(struct object_collection *coll) -Index: openvswitch-2.17.2/lib/odp-execute.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/odp-execute.c -+++ openvswitch-2.17.2/lib/odp-execute.c -@@ -25,17 +25,17 @@ - #include - #include - --#include "coverage.h" --#include "dp-packet.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" - #include "dpif.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "odp-netlink.h" - #include "odp-util.h" --#include "packets.h" --#include "flow.h" --#include "unaligned.h" --#include "util.h" --#include "csum.h" -+#include "internal/packets.h" -+#include "internal/flow.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" -+#include "internal/csum.h" - #include "conntrack.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/lib/odp-util.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/odp-util.c -+++ openvswitch-2.17.2/lib/odp-util.c -@@ -27,24 +27,24 @@ - #include - #include - --#include "byte-order.h" --#include "coverage.h" -+#include "internal/byte-order.h" -+#include "internal/coverage.h" - #include "dpif.h" - #include "openvswitch/dynamic-string.h" --#include "flow.h" --#include "netlink.h" -+#include "internal/flow.h" -+#include "internal/netlink.h" - #include "openvswitch/ofpbuf.h" --#include "packets.h" --#include "simap.h" --#include "timeval.h" --#include "tun-metadata.h" --#include "unaligned.h" --#include "util.h" --#include "uuid.h" -+#include "internal/packets.h" -+#include "internal/simap.h" -+#include "internal/timeval.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - #include "openvswitch/vlog.h" - #include "openvswitch/match.h" - #include "odp-netlink-macros.h" --#include "csum.h" -+#include "internal/csum.h" - - VLOG_DEFINE_THIS_MODULE(odp_util); - -Index: openvswitch-2.17.2/lib/odp-util.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/odp-util.h -+++ openvswitch-2.17.2/lib/odp-util.h -@@ -21,14 +21,14 @@ - #include - #include - #include --#include "flow.h" --#include "hash.h" -+#include "internal/flow.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/uuid.h" - #include "odp-netlink.h" - #include "openflow/openflow.h" --#include "util.h" -+#include "internal/util.h" - - struct ds; - struct nlattr; -Index: openvswitch-2.17.2/lib/ofp-actions.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-actions.c -+++ openvswitch-2.17.2/lib/ofp-actions.c -@@ -19,15 +19,15 @@ - #include - #include - --#include "bundle.h" --#include "byte-order.h" --#include "colors.h" -+#include "internal/bundle.h" -+#include "internal/byte-order.h" -+#include "internal/colors.h" - #include "openvswitch/compiler.h" - #include "dummy.h" - #include "openvswitch/hmap.h" - #include "learn.h" - #include "multipath.h" --#include "nx-match.h" -+#include "internal/nx-match.h" - #include "odp-netlink.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/meta-flow.h" -@@ -39,8 +39,8 @@ - #include "openvswitch/ofp-table.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "vl-mff-map.h" - - VLOG_DEFINE_THIS_MODULE(ofp_actions); -Index: openvswitch-2.17.2/lib/ofp-bundle.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-bundle.c -+++ openvswitch-2.17.2/lib/ofp-bundle.c -@@ -22,7 +22,7 @@ - #include "openvswitch/ofp-print.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_bundle); - -Index: openvswitch-2.17.2/lib/ofp-connection.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-connection.c -+++ openvswitch-2.17.2/lib/ofp-connection.c -@@ -16,7 +16,7 @@ - - #include - #include "openvswitch/ofp-connection.h" --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openflow/nicira-ext.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-monitor.h" -@@ -27,7 +27,7 @@ - #include "openvswitch/ofpbuf.h" - #include "openvswitch/type-props.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_connection); - -Index: openvswitch-2.17.2/lib/ofp-ed-props.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-ed-props.c -+++ openvswitch-2.17.2/lib/ofp-ed-props.c -@@ -21,8 +21,8 @@ - #include "openvswitch/ofp-ed-props.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/ofp-parse.h" --#include "util.h" --#include "lib/packets.h" -+#include "internal/util.h" -+#include "internal/packets.h" - - - enum ofperr -Index: openvswitch-2.17.2/lib/ofp-errors.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-errors.c -+++ openvswitch-2.17.2/lib/ofp-errors.c -@@ -16,7 +16,7 @@ - - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openflow/openflow.h" - #include "openflow/nicira-ext.h" - #include "openvswitch/dynamic-string.h" -@@ -25,7 +25,7 @@ - #include "openvswitch/ofp-print.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_errors); - -Index: openvswitch-2.17.2/lib/ofp-flow.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-flow.c -+++ openvswitch-2.17.2/lib/ofp-flow.c -@@ -17,10 +17,10 @@ - #include - #include "openvswitch/ofp-flow.h" - #include --#include "byte-order.h" --#include "colors.h" --#include "flow.h" --#include "nx-match.h" -+#include "internal/byte-order.h" -+#include "internal/colors.h" -+#include "internal/flow.h" -+#include "internal/nx-match.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofp-group.h" - #include "openvswitch/ofp-match.h" -@@ -31,7 +31,7 @@ - #include "openvswitch/ofp-table.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - #include "ox-stat.h" - - VLOG_DEFINE_THIS_MODULE(ofp_flow); -Index: openvswitch-2.17.2/lib/ofp-group.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-group.c -+++ openvswitch-2.17.2/lib/ofp-group.c -@@ -17,9 +17,9 @@ - #include - #include "openvswitch/ofp-group.h" - #include --#include "byte-order.h" --#include "id-pool.h" --#include "nx-match.h" -+#include "internal/byte-order.h" -+#include "internal/id-pool.h" -+#include "internal/nx-match.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/ofp-msgs.h" -@@ -29,7 +29,7 @@ - #include "openvswitch/ofp-prop.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_group); - -Index: openvswitch-2.17.2/lib/ofp-ipfix.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-ipfix.c -+++ openvswitch-2.17.2/lib/ofp-ipfix.c -@@ -17,12 +17,12 @@ - #include - #include "openvswitch/ofp-ipfix.h" - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openflow/nicira-ext.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofpbuf.h" --#include "util.h" -+#include "internal/util.h" - - static void - ofputil_ipfix_stats_to_reply(const struct ofputil_ipfix_stats *ois, -Index: openvswitch-2.17.2/lib/ofp-match.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-match.c -+++ openvswitch-2.17.2/lib/ofp-match.c -@@ -16,9 +16,9 @@ - - #include - #include "openvswitch/ofp-match.h" --#include "byte-order.h" --#include "flow.h" --#include "nx-match.h" -+#include "internal/byte-order.h" -+#include "internal/flow.h" -+#include "internal/nx-match.h" - #include "openvswitch/match.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-msgs.h" -Index: openvswitch-2.17.2/lib/ofp-meter.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-meter.c -+++ openvswitch-2.17.2/lib/ofp-meter.c -@@ -16,8 +16,8 @@ - - #include - #include "openvswitch/ofp-meter.h" --#include "byte-order.h" --#include "nx-match.h" -+#include "internal/byte-order.h" -+#include "internal/nx-match.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofp-parse.h" -Index: openvswitch-2.17.2/lib/ofp-monitor.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-monitor.c -+++ openvswitch-2.17.2/lib/ofp-monitor.c -@@ -16,9 +16,9 @@ - - #include - #include "openvswitch/ofp-monitor.h" --#include "byte-order.h" --#include "nx-match.h" --#include "ovs-atomic.h" -+#include "internal/byte-order.h" -+#include "internal/nx-match.h" -+#include "openvswitch/ovs-atomic.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-group.h" -Index: openvswitch-2.17.2/lib/ofp-msgs.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-msgs.c -+++ openvswitch-2.17.2/lib/ofp-msgs.c -@@ -15,8 +15,8 @@ - */ - - #include --#include "byte-order.h" --#include "hash.h" -+#include "internal/byte-order.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "openflow/nicira-ext.h" - #include "openflow/openflow.h" -@@ -24,8 +24,8 @@ - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "ovs-thread.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_msgs); - -Index: openvswitch-2.17.2/lib/ofp-packet.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-packet.c -+++ openvswitch-2.17.2/lib/ofp-packet.c -@@ -17,8 +17,8 @@ - #include - #include "openvswitch/ofp-packet.h" - #include --#include "dp-packet.h" --#include "nx-match.h" -+#include "internal/dp-packet.h" -+#include "internal/nx-match.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-msgs.h" -@@ -29,8 +29,8 @@ - #include "openvswitch/ofp-table.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" --#include "uuid.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(ofp_packet); - -Index: openvswitch-2.17.2/lib/ofp-parse.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-parse.c -+++ openvswitch-2.17.2/lib/ofp-parse.c -@@ -17,16 +17,16 @@ - #include - #include "openvswitch/ofp-parse.h" - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/match.h" - #include "openvswitch/meta-flow.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofp-flow.h" - #include "openvswitch/ofp-match.h" - #include "openvswitch/ofp-table.h" --#include "packets.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - - /* Parses 'str' as an 8-bit unsigned integer into '*valuep'. - * -Index: openvswitch-2.17.2/lib/ofp-port.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-port.c -+++ openvswitch-2.17.2/lib/ofp-port.c -@@ -17,8 +17,8 @@ - #include - #include "openvswitch/ofp-port.h" - #include --#include "byte-order.h" --#include "flow.h" -+#include "internal/byte-order.h" -+#include "internal/flow.h" - #include "openflow/intel-ext.h" - #include "openvswitch/json.h" - #include "openvswitch/ofp-errors.h" -Index: openvswitch-2.17.2/lib/ofp-print.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-print.c -+++ openvswitch-2.17.2/lib/ofp-print.c -@@ -27,16 +27,16 @@ - #include - #include - --#include "bundle.h" --#include "byte-order.h" --#include "colors.h" -+#include "internal/bundle.h" -+#include "internal/byte-order.h" -+#include "internal/colors.h" - #include "openvswitch/compiler.h" --#include "dp-packet.h" --#include "flow.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" - #include "learn.h" - #include "multipath.h" --#include "netdev.h" --#include "nx-match.h" -+#include "internal/netdev.h" -+#include "internal/nx-match.h" - #include "odp-util.h" - #include "openflow/nicira-ext.h" - #include "openflow/openflow.h" -@@ -59,10 +59,10 @@ - #include "openvswitch/ofp-util.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/type-props.h" --#include "packets.h" --#include "unaligned.h" --#include "util.h" --#include "uuid.h" -+#include "internal/packets.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - static void ofp_print_error(struct ds *, enum ofperr); - -Index: openvswitch-2.17.2/lib/ofp-prop.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-prop.c -+++ openvswitch-2.17.2/lib/ofp-prop.c -@@ -16,13 +16,13 @@ - - #include - --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-prop.h" - #include "openvswitch/vlog.h" --#include "util.h" --#include "uuid.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - struct ofp_prop_be16 { - ovs_be16 type; -Index: openvswitch-2.17.2/lib/ofp-protocol.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-protocol.c -+++ openvswitch-2.17.2/lib/ofp-protocol.c -@@ -22,7 +22,7 @@ - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_protocol); - -Index: openvswitch-2.17.2/lib/ofp-queue.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-queue.c -+++ openvswitch-2.17.2/lib/ofp-queue.c -@@ -16,15 +16,15 @@ - - #include - #include "openvswitch/ofp-queue.h" --#include "byte-order.h" --#include "flow.h" -+#include "internal/byte-order.h" -+#include "internal/flow.h" - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofp-print.h" - #include "openvswitch/ofp-port.h" - #include "openvswitch/ofp-prop.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_queue); - -Index: openvswitch-2.17.2/lib/ofp-switch.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-switch.c -+++ openvswitch-2.17.2/lib/ofp-switch.c -@@ -16,14 +16,14 @@ - - #include - #include "openvswitch/ofp-switch.h" --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofp-port.h" - #include "openvswitch/ofp-print.h" --#include "util.h" -+#include "internal/util.h" - - /* ofputil_switch_features */ - -Index: openvswitch-2.17.2/lib/ofp-table.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-table.c -+++ openvswitch-2.17.2/lib/ofp-table.c -@@ -16,8 +16,8 @@ - - #include - #include "openvswitch/ofp-table.h" --#include "bitmap.h" --#include "nx-match.h" -+#include "internal/bitmap.h" -+#include "internal/nx-match.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" - #include "openvswitch/ofp-actions.h" -@@ -26,7 +26,7 @@ - #include "openvswitch/ofp-prop.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofp_table); - -Index: openvswitch-2.17.2/lib/ofp-util.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-util.c -+++ openvswitch-2.17.2/lib/ofp-util.c -@@ -23,15 +23,15 @@ - #include - #include - #include --#include "bitmap.h" --#include "bundle.h" --#include "byte-order.h" --#include "classifier.h" -+#include "internal/bitmap.h" -+#include "internal/bundle.h" -+#include "internal/byte-order.h" -+#include "internal/classifier.h" - #include "learn.h" - #include "multipath.h" --#include "netdev.h" --#include "nx-match.h" --#include "id-pool.h" -+#include "internal/netdev.h" -+#include "internal/nx-match.h" -+#include "internal/id-pool.h" - #include "openflow/netronome-ext.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" -@@ -45,12 +45,12 @@ - #include "openvswitch/type-props.h" - #include "openvswitch/vlog.h" - #include "openflow/intel-ext.h" --#include "packets.h" --#include "random.h" --#include "tun-metadata.h" --#include "unaligned.h" --#include "util.h" --#include "uuid.h" -+#include "internal/packets.h" -+#include "internal/random.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(ofp_util); - -Index: openvswitch-2.17.2/lib/ofp-version-opt.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-version-opt.c -+++ openvswitch-2.17.2/lib/ofp-version-opt.c -@@ -2,7 +2,7 @@ - #include "openvswitch/dynamic-string.h" - #include "openvswitch/ofp-protocol.h" - #include "ofp-version-opt.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - - static uint32_t allowed_versions = 0; - -Index: openvswitch-2.17.2/lib/ofp-version-opt.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofp-version-opt.h -+++ openvswitch-2.17.2/lib/ofp-version-opt.h -@@ -2,7 +2,7 @@ - #define OFP_VERSION_H 1 - - #include --#include "util.h" -+#include "internal/util.h" - - #define OFP_VERSION_LONG_OPTIONS \ - {"version", no_argument, NULL, 'V'}, \ -Index: openvswitch-2.17.2/lib/ofpbuf.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ofpbuf.c -+++ openvswitch-2.17.2/lib/ofpbuf.c -@@ -19,7 +19,7 @@ - #include - #include - #include "openvswitch/dynamic-string.h" --#include "util.h" -+#include "internal/util.h" - - static void - ofpbuf_init__(struct ofpbuf *b, size_t allocated, enum ofpbuf_source source) -Index: openvswitch-2.17.2/lib/ovs-lldp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-lldp.c -+++ openvswitch-2.17.2/lib/ovs-lldp.c -@@ -35,17 +35,17 @@ - #include - #include - #include "openvswitch/dynamic-string.h" --#include "flow.h" -+#include "internal/flow.h" - #include "openvswitch/list.h" - #include "lldp/lldpd.h" - #include "lldp/lldpd-structs.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "openvswitch/types.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "smap.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/smap.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovs_lldp); -Index: openvswitch-2.17.2/lib/ovs-lldp.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-lldp.h -+++ openvswitch-2.17.2/lib/ovs-lldp.h -@@ -20,13 +20,13 @@ - #define OVS_LLDP_H - - #include --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" - #include "lldp/lldpd.h" --#include "ovs-atomic.h" --#include "packets.h" --#include "timer.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/packets.h" -+#include "internal/timer.h" - - /* Transmit every LLDPD_TX_INTERVAL seconds. */ - #define LLDP_DEFAULT_TRANSMIT_INTERVAL_MS (LLDPD_TX_INTERVAL * 1000) -Index: openvswitch-2.17.2/lib/ovs-numa.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-numa.c -+++ openvswitch-2.17.2/lib/ovs-numa.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "ovs-numa.h" -+#include "openvswitch/ovs-numa.h" - - #include - #include -@@ -27,12 +27,12 @@ - #include - #endif /* __linux__ */ - --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ovs_numa); - -Index: openvswitch-2.17.2/lib/ovs-rcu.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-rcu.c -+++ openvswitch-2.17.2/lib/ovs-rcu.c -@@ -16,16 +16,16 @@ - - #include - #include --#include "ovs-rcu.h" --#include "fatal-signal.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/fatal-signal.h" - #include "guarded-list.h" --#include "latch.h" -+#include "internal/latch.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" --#include "timeval.h" --#include "util.h" -+#include "internal/seq.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovs_rcu); -Index: openvswitch-2.17.2/lib/ovs-replay.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-replay.c -+++ openvswitch-2.17.2/lib/ovs-replay.c -@@ -22,10 +22,10 @@ - #include - #include - #include --#include "dirs.h" --#include "ovs-atomic.h" -+#include "internal/dirs.h" -+#include "openvswitch/ovs-atomic.h" - #include "ovs-replay.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovs_replay); -Index: openvswitch-2.17.2/lib/ovs-router.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-router.c -+++ openvswitch-2.17.2/lib/ovs-router.c -@@ -30,21 +30,21 @@ - #include - #include - --#include "classifier.h" --#include "colors.h" -+#include "internal/classifier.h" -+#include "internal/command-line.h" - #include "openvswitch/compiler.h" - #include "dpif.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/dynamic-string.h" --#include "netdev.h" --#include "packets.h" --#include "seq.h" --#include "ovs-thread.h" -+#include "internal/netdev.h" -+#include "internal/packets.h" -+#include "internal/seq.h" -+#include "openvswitch/ovs-thread.h" - #include "route-table.h" - #include "tnl-ports.h" --#include "unixctl.h" --#include "util.h" --#include "unaligned.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" -+#include "internal/unaligned.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovs_router); -Index: openvswitch-2.17.2/lib/ovs-router.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-router.h -+++ openvswitch-2.17.2/lib/ovs-router.h -@@ -20,7 +20,7 @@ - #include - #include - --#include "util.h" -+#include "internal/util.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/lib/ovs-thread.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-thread.c -+++ openvswitch-2.17.2/lib/ovs-thread.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include - #include - #ifndef _WIN32 -@@ -24,14 +24,14 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/list.h" --#include "ovs-rcu.h" -+#include "openvswitch/ovs-rcu.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/seq.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - - #ifdef __CHECKER__ - /* Omit the definitions in this file because they are somewhat difficult to -Index: openvswitch-2.17.2/lib/ovsdb-condition.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-condition.c -+++ openvswitch-2.17.2/lib/ovsdb-condition.c -@@ -16,8 +16,8 @@ - #include - - #include --#include "ovsdb-error.h" --#include "ovsdb-condition.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-condition.h" - - struct ovsdb_error * - ovsdb_function_from_string(const char *name, enum ovsdb_function *function) -Index: openvswitch-2.17.2/lib/ovsdb-cs.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-cs.c -+++ openvswitch-2.17.2/lib/ovsdb-cs.c -@@ -16,27 +16,27 @@ - - #include - --#include "ovsdb-cs.h" -+#include "openvswitch/ovsdb-cs.h" - - #include - --#include "hash.h" --#include "jsonrpc.h" -+#include "internal/hash.h" -+#include "internal/jsonrpc.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/hmap.h" - #include "openvswitch/json.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" - #include "openvswitch/vlog.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "ovsdb-session.h" --#include "ovsdb-types.h" --#include "sset.h" --#include "svec.h" --#include "util.h" --#include "uuid.h" -+#include "openvswitch/ovsdb-types.h" -+#include "internal/sset.h" -+#include "internal/svec.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_cs); - -Index: openvswitch-2.17.2/lib/ovsdb-data.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-data.c -+++ openvswitch-2.17.2/lib/ovsdb-data.c -@@ -15,7 +15,7 @@ - - #include - --#include "ovsdb-data.h" -+#include "openvswitch/ovsdb-data.h" - - #include - #include -@@ -23,16 +23,16 @@ - #include - - #include "openvswitch/dynamic-string.h" --#include "hash.h" --#include "ovs-thread.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "internal/hash.h" -+#include "openvswitch/ovs-thread.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "openvswitch/json.h" - #include "openvswitch/shash.h" --#include "smap.h" --#include "sort.h" -+#include "internal/smap.h" -+#include "internal/sort.h" - #include "unicode.h" --#include "util.h" -+#include "internal/util.h" - - static struct json * - wrap_json(const char *name, struct json *wrapped) -Index: openvswitch-2.17.2/lib/ovsdb-error.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-error.c -+++ openvswitch-2.17.2/lib/ovsdb-error.c -@@ -15,14 +15,14 @@ - - #include - --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - - #include - - #include "backtrace.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_error); -Index: openvswitch-2.17.2/lib/ovsdb-idl.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-idl.c -+++ openvswitch-2.17.2/lib/ovsdb-idl.c -@@ -16,37 +16,37 @@ - - #include - --#include "ovsdb-idl.h" -+#include "openvswitch/ovsdb-idl.h" - - #include - #include - #include - #include - --#include "bitmap.h" --#include "coverage.h" --#include "hash.h" -+#include "internal/bitmap.h" -+#include "internal/coverage.h" -+#include "internal/hash.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include "ovsdb/ovsdb.h" - #include "ovsdb/table.h" --#include "ovsdb-cs.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "ovsdb-idl-provider.h" --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-cs.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-idl-provider.h" -+#include "openvswitch/ovsdb-parser.h" - #include "ovsdb-server-idl.h" - #include "ovsdb-session.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "skiplist.h" --#include "simap.h" --#include "sset.h" --#include "svec.h" --#include "util.h" --#include "uuid.h" -+#include "internal/skiplist.h" -+#include "internal/simap.h" -+#include "internal/sset.h" -+#include "internal/svec.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_idl); -Index: openvswitch-2.17.2/lib/ovsdb-map-op.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-map-op.c -+++ openvswitch-2.17.2/lib/ovsdb-map-op.c -@@ -15,10 +15,10 @@ -  */ - - #include --#include "ovsdb-map-op.h" --#include "util.h" -+#include "openvswitch/ovsdb-map-op.h" -+#include "internal/util.h" - #include "openvswitch/hmap.h" --#include "hash.h" -+#include "internal/hash.h" - - /* Map Operation: a Partial Map Update */ - struct map_op { -Index: openvswitch-2.17.2/lib/ovsdb-parser.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-parser.c -+++ openvswitch-2.17.2/lib/ovsdb-parser.c -@@ -15,12 +15,12 @@ - - #include - --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-parser.h" - - #include - #include - --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - - void - ovsdb_parser_init(struct ovsdb_parser *parser, const struct json *json, -Index: openvswitch-2.17.2/lib/ovsdb-session.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-session.c -+++ openvswitch-2.17.2/lib/ovsdb-session.c -@@ -18,9 +18,9 @@ - #include - #include - #include --#include "svec.h" --#include "util.h" --#include "uuid.h" -+#include "internal/svec.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - static const char * - next_remote(const char *s) -Index: openvswitch-2.17.2/lib/ovsdb-set-op.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-set-op.c -+++ openvswitch-2.17.2/lib/ovsdb-set-op.c -@@ -16,8 +16,8 @@ - */ - - #include --#include "ovsdb-set-op.h" --#include "util.h" -+#include "openvswitch/ovsdb-set-op.h" -+#include "internal/util.h" - - /* Set Operation: a Partial Set Update */ - struct set_op { -Index: openvswitch-2.17.2/lib/ovsdb-types.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovsdb-types.c -+++ openvswitch-2.17.2/lib/ovsdb-types.c -@@ -15,18 +15,18 @@ - - #include - --#include "ovsdb-types.h" -+#include "openvswitch/ovsdb-types.h" - - #include - #include - - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "ovs-thread.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" -+#include "internal/util.h" - - const struct ovsdb_type ovsdb_type_integer = - OVSDB_TYPE_SCALAR_INITIALIZER(OVSDB_BASE_INTEGER_INIT); -Index: openvswitch-2.17.2/lib/ox-stat.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/ox-stat.c -+++ openvswitch-2.17.2/lib/ox-stat.c -@@ -16,12 +16,12 @@ - - #include - #include "ox-stat.h" --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/ofp-errors.h" - #include "openvswitch/compiler.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "unaligned.h" -+#include "internal/unaligned.h" - - VLOG_DEFINE_THIS_MODULE(ox_stat); - -Index: openvswitch-2.17.2/lib/packets.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/packets.c -+++ openvswitch-2.17.2/lib/packets.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "packets.h" -+#include "internal/packets.h" - #include - #include - #include -@@ -24,16 +24,16 @@ - #include - #include - #include --#include "byte-order.h" --#include "csum.h" --#include "crc32c.h" --#include "flow.h" -+#include "internal/byte-order.h" -+#include "internal/csum.h" -+#include "internal/crc32c.h" -+#include "internal/flow.h" - #include "openvswitch/hmap.h" - #include "openvswitch/dynamic-string.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "odp-util.h" --#include "dp-packet.h" --#include "unaligned.h" -+#include "internal/dp-packet.h" -+#include "internal/unaligned.h" - - const struct in6_addr in6addr_exact = IN6ADDR_EXACT_INIT; - const struct in6_addr in6addr_all_hosts = IN6ADDR_ALL_HOSTS_INIT; -Index: openvswitch-2.17.2/lib/pcap-file.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/pcap-file.c -+++ openvswitch-2.17.2/lib/pcap-file.c -@@ -21,15 +21,15 @@ - #include - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "openvswitch/compiler.h" --#include "dp-packet.h" --#include "flow.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" - #include "openvswitch/hmap.h" --#include "packets.h" --#include "timeval.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(pcap); -Index: openvswitch-2.17.2/lib/perf-counter.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/perf-counter.c -+++ openvswitch-2.17.2/lib/perf-counter.c -@@ -29,7 +29,7 @@ - #include "openvswitch/dynamic-string.h" - #include "perf-counter.h" - #include "openvswitch/shash.h" --#include "util.h" -+#include "internal/util.h" - - static struct shash perf_counters = SHASH_INITIALIZER(&perf_counters); - static int fd__ = 0; -Index: openvswitch-2.17.2/lib/poll-loop.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/poll-loop.c -+++ openvswitch-2.17.2/lib/poll-loop.c -@@ -21,17 +21,17 @@ - #include - #include - #include --#include "coverage.h" -+#include "internal/coverage.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" --#include "seq.h" --#include "socket-util.h" --#include "timeval.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/seq.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" - #include "openvswitch/vlog.h" - #include "openvswitch/hmap.h" --#include "hash.h" -+#include "internal/hash.h" - - VLOG_DEFINE_THIS_MODULE(poll_loop); - -Index: openvswitch-2.17.2/lib/process.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/process.c -+++ openvswitch-2.17.2/lib/process.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "process.h" -+#include "internal/process.h" - #include - #include - #include -@@ -25,16 +25,16 @@ - #include - #include - #include --#include "coverage.h" -+#include "internal/coverage.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" - #include "signals.h" --#include "socket-util.h" --#include "timeval.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(process); -Index: openvswitch-2.17.2/lib/pvector.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/pvector.c -+++ openvswitch-2.17.2/lib/pvector.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "pvector.h" -+#include "internal/pvector.h" - - /* Writers will preallocate space for some entries at the end to avoid future - * reallocations. */ -Index: openvswitch-2.17.2/lib/random.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/random.c -+++ openvswitch-2.17.2/lib/random.c -@@ -15,17 +15,17 @@ - */ - - #include --#include "random.h" -+#include "internal/random.h" - - #include - #include - #include - - #include "entropy.h" --#include "hash.h" --#include "ovs-thread.h" --#include "timeval.h" --#include "util.h" -+#include "internal/hash.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - /* This is the 32-bit PRNG recommended in G. Marsaglia, "Xorshift RNGs", - * _Journal of Statistical Software_ 8:14 (July 2003). According to the paper, -Index: openvswitch-2.17.2/lib/rconn.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/rconn.c -+++ openvswitch-2.17.2/lib/rconn.c -@@ -20,7 +20,7 @@ - #include - #include - #include --#include "coverage.h" -+#include "internal/coverage.h" - #include "openflow/openflow.h" - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofp-util.h" -@@ -29,10 +29,10 @@ - #include "openvswitch/vlog.h" - #include "openvswitch/poll-loop.h" - #include "sat-math.h" --#include "stream.h" --#include "timeval.h" --#include "util.h" --#include "ovs-thread.h" -+#include "internal/stream.h" -+#include "internal/timeval.h" -+#include "internal/util.h" -+#include "openvswitch/ovs-thread.h" - - VLOG_DEFINE_THIS_MODULE(rconn); - -Index: openvswitch-2.17.2/lib/reconnect.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/reconnect.c -+++ openvswitch-2.17.2/lib/reconnect.c -@@ -20,7 +20,7 @@ - #include - - #include "openvswitch/poll-loop.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(reconnect); -Index: openvswitch-2.17.2/lib/route-table-bsd.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/route-table-bsd.c -+++ openvswitch-2.17.2/lib/route-table-bsd.c -@@ -32,9 +32,9 @@ - #include - - #include "ovs-router.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(route_table_bsd); - -Index: openvswitch-2.17.2/lib/route-table.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/route-table.c -+++ openvswitch-2.17.2/lib/route-table.c -@@ -26,14 +26,14 @@ - #include - #include - --#include "hash.h" --#include "netdev.h" --#include "netlink.h" -+#include "internal/hash.h" -+#include "internal/netdev.h" -+#include "internal/netlink.h" - #include "netlink-notifier.h" - #include "netlink-socket.h" - #include "openvswitch/ofpbuf.h" - #include "ovs-router.h" --#include "packets.h" -+#include "internal/packets.h" - #include "rtnetlink.h" - #include "tnl-ports.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/lib/rstp-common.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/rstp-common.h -+++ openvswitch-2.17.2/lib/rstp-common.h -@@ -35,8 +35,8 @@ - #include - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" --#include "ovs-atomic.h" --#include "packets.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/packets.h" - - enum admin_port_state { - RSTP_ADMIN_BRIDGE_PORT_STATE_DISABLED = 0, -Index: openvswitch-2.17.2/lib/rstp-state-machines.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/rstp-state-machines.c -+++ openvswitch-2.17.2/lib/rstp-state-machines.c -@@ -36,14 +36,14 @@ - #include - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "connectivity.h" - #include "openvswitch/ofpbuf.h" --#include "dp-packet.h" --#include "packets.h" --#include "seq.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" -+#include "internal/seq.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(rstp_sm); -Index: openvswitch-2.17.2/lib/rstp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/rstp.c -+++ openvswitch-2.17.2/lib/rstp.c -@@ -37,15 +37,15 @@ - #include - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "connectivity.h" - #include "openvswitch/ofpbuf.h" - #include "ofproto/ofproto.h" --#include "dp-packet.h" --#include "packets.h" --#include "seq.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" -+#include "internal/seq.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(rstp); -Index: openvswitch-2.17.2/lib/rstp.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/rstp.h -+++ openvswitch-2.17.2/lib/rstp.h -@@ -34,7 +34,7 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "util.h" -+#include "internal/util.h" - - /* Thread Safety: Callers passing in RSTP and RSTP port object - * pointers must hold a reference to the passed object to ensure that -Index: openvswitch-2.17.2/lib/rtbsd.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/rtbsd.c -+++ openvswitch-2.17.2/lib/rtbsd.c -@@ -25,8 +25,8 @@ - #include - #include - --#include "coverage.h" --#include "socket-util.h" -+#include "internal/coverage.h" -+#include "internal/socket-util.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/lib/rtnetlink.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/rtnetlink.c -+++ openvswitch-2.17.2/lib/rtnetlink.c -@@ -22,10 +22,10 @@ - #include - #include - --#include "netlink.h" -+#include "internal/netlink.h" - #include "netlink-notifier.h" - #include "openvswitch/ofpbuf.h" --#include "packets.h" -+#include "internal/packets.h" - - #if IFLA_INFO_MAX < 5 - #define IFLA_INFO_SLAVE_KIND 4 -Index: openvswitch-2.17.2/lib/seq.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/seq.c -+++ openvswitch-2.17.2/lib/seq.c -@@ -16,16 +16,16 @@ - - #include - --#include "seq.h" -+#include "internal/seq.h" - - #include - --#include "coverage.h" --#include "hash.h" -+#include "internal/coverage.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "latch.h" -+#include "internal/latch.h" - #include "openvswitch/list.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" - - COVERAGE_DEFINE(seq_change); -Index: openvswitch-2.17.2/lib/sflow_agent.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/sflow_agent.c -+++ openvswitch-2.17.2/lib/sflow_agent.c -@@ -6,7 +6,7 @@ - */ - - #include "sflow_api.h" --#include "util.h" -+#include "internal/util.h" - - static void * sflAlloc(SFLAgent *agent, size_t bytes); - static void sflFree(SFLAgent *agent, void *obj); -Index: openvswitch-2.17.2/lib/sha1.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/sha1.c -+++ openvswitch-2.17.2/lib/sha1.c -@@ -34,7 +34,7 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "util.h" -+#include "internal/util.h" - - /* a bit faster & bigger, if defined */ - #define UNROLL_LOOPS -Index: openvswitch-2.17.2/lib/shash.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/shash.c -+++ openvswitch-2.17.2/lib/shash.c -@@ -16,7 +16,7 @@ - - #include - #include "openvswitch/shash.h" --#include "hash.h" -+#include "internal/hash.h" - - static struct shash_node *shash_find__(const struct shash *, - const char *name, size_t name_len, -Index: openvswitch-2.17.2/lib/signals.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/signals.c -+++ openvswitch-2.17.2/lib/signals.c -@@ -22,9 +22,9 @@ - #include - #include - #include "openvswitch/poll-loop.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - #include "openvswitch/type-props.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(signals); -Index: openvswitch-2.17.2/lib/simap.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/simap.c -+++ openvswitch-2.17.2/lib/simap.c -@@ -15,8 +15,8 @@ - */ - - #include --#include "simap.h" --#include "hash.h" -+#include "internal/simap.h" -+#include "internal/hash.h" - - static size_t hash_name(const char *, size_t length); - static struct simap_node *simap_find__(const struct simap *, -Index: openvswitch-2.17.2/lib/skiplist.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/skiplist.c -+++ openvswitch-2.17.2/lib/skiplist.c -@@ -25,9 +25,9 @@ - #include - #include - --#include "skiplist.h" --#include "random.h" --#include "util.h" -+#include "internal/skiplist.h" -+#include "internal/random.h" -+#include "internal/util.h" - - /* - * A maximum height level of 32 should be more than sufficient for -Index: openvswitch-2.17.2/lib/smap.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/smap.c -+++ openvswitch-2.17.2/lib/smap.c -@@ -13,15 +13,15 @@ - * limitations under the License. */ - - #include --#include "smap.h" -+#include "internal/smap.h" - - #include - --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/json.h" --#include "packets.h" --#include "util.h" --#include "uuid.h" -+#include "internal/packets.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - static struct smap_node *smap_add__(struct smap *, char *, void *, - size_t hash); -Index: openvswitch-2.17.2/lib/socket-util-unix.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/socket-util-unix.c -+++ openvswitch-2.17.2/lib/socket-util-unix.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "socket-util.h" -+#include "internal/socket-util.h" - #include - #include - #include -@@ -25,9 +25,9 @@ - #include - #include - #include --#include "fatal-signal.h" --#include "random.h" --#include "util.h" -+#include "internal/fatal-signal.h" -+#include "internal/random.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(socket_util_unix); -Index: openvswitch-2.17.2/lib/socket-util.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/socket-util.c -+++ openvswitch-2.17.2/lib/socket-util.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "socket-util.h" -+#include "internal/socket-util.h" - #include - #include - #include -@@ -36,16 +36,16 @@ - #include - #include - #include "openvswitch/dynamic-string.h" --#include "ovs-thread.h" --#include "packets.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - #ifdef __linux__ - #include - #endif - #ifdef HAVE_NETLINK --#include "netlink-protocol.h" -+#include "internal/netlink-protocol.h" - #include "netlink-socket.h" - #endif - #include "dns-resolve.h" -Index: openvswitch-2.17.2/lib/sort.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/sort.c -+++ openvswitch-2.17.2/lib/sort.c -@@ -15,9 +15,9 @@ - - #include - --#include "sort.h" -+#include "internal/sort.h" - --#include "random.h" -+#include "internal/random.h" - - static size_t - partition(size_t p, size_t r, -Index: openvswitch-2.17.2/lib/sset.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/sset.c -+++ openvswitch-2.17.2/lib/sset.c -@@ -16,10 +16,10 @@ - - #include - --#include "sset.h" -+#include "internal/sset.h" - - #include "openvswitch/dynamic-string.h" --#include "hash.h" -+#include "internal/hash.h" - - static uint32_t - hash_name__(const char *name, size_t length) -Index: openvswitch-2.17.2/lib/stopwatch.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stopwatch.c -+++ openvswitch-2.17.2/lib/stopwatch.c -@@ -15,17 +15,17 @@ - - #include - --#include "stopwatch.h" -+#include "internal/stopwatch.h" - #include "openvswitch/shash.h" - #include "openvswitch/vlog.h" --#include "unixctl.h" -+#include "internal/unixctl.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/poll-loop.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include --#include "socket-util.h" --#include "util.h" --#include "latch.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" -+#include "internal/latch.h" - #include "guarded-list.h" - - VLOG_DEFINE_THIS_MODULE(stopwatch); -Index: openvswitch-2.17.2/lib/stp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stp.c -+++ openvswitch-2.17.2/lib/stp.c -@@ -25,15 +25,15 @@ - #include - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "connectivity.h" - #include "openvswitch/ofpbuf.h" --#include "ovs-atomic.h" --#include "dp-packet.h" --#include "packets.h" --#include "seq.h" --#include "unixctl.h" --#include "util.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" -+#include "internal/seq.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(stp); -Index: openvswitch-2.17.2/lib/stp.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/stp.h -+++ openvswitch-2.17.2/lib/stp.h -@@ -23,7 +23,7 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "util.h" -+#include "internal/util.h" - - struct dp_packet; - -Index: openvswitch-2.17.2/lib/stream-fd.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-fd.c -+++ openvswitch-2.17.2/lib/stream-fd.c -@@ -23,12 +23,12 @@ - #include - #include - #include --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/poll-loop.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - #include "stream-provider.h" --#include "stream.h" -+#include "internal/stream.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(stream_fd); -Index: openvswitch-2.17.2/lib/stream-nossl.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-nossl.c -+++ openvswitch-2.17.2/lib/stream-nossl.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "stream-ssl.h" -+#include "internal/stream-ssl.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(stream_nossl); -Index: openvswitch-2.17.2/lib/stream-provider.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-provider.h -+++ openvswitch-2.17.2/lib/stream-provider.h -@@ -19,7 +19,7 @@ - - #include - #include "ovs-replay.h" --#include "stream.h" -+#include "internal/stream.h" - - /* Active stream connection. */ - -Index: openvswitch-2.17.2/lib/stream-replay.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-replay.c -+++ openvswitch-2.17.2/lib/stream-replay.c -@@ -23,11 +23,11 @@ - #include - #include - #include --#include "ovs-atomic.h" -+#include "openvswitch/ovs-atomic.h" - #include "ovs-replay.h" --#include "util.h" -+#include "internal/util.h" - #include "stream-provider.h" --#include "stream.h" -+#include "internal/stream.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/lib/stream-ssl.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-ssl.c -+++ openvswitch-2.17.2/lib/stream-ssl.c -@@ -15,8 +15,8 @@ - */ - - #include --#include "stream-ssl.h" --#include "dhparams.h" -+#include "internal/stream-ssl.h" -+#include "internal/dhparams.h" - #include - #include - #include -@@ -32,19 +32,19 @@ - #include - #include - #include --#include "coverage.h" -+#include "internal/coverage.h" - #include "openvswitch/dynamic-string.h" - #include "entropy.h" - #include "openvswitch/ofpbuf.h" - #include "openflow/openflow.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - #include "stream-provider.h" --#include "stream.h" --#include "timeval.h" -+#include "internal/stream.h" -+#include "internal/timeval.h" - #include "openvswitch/vlog.h" - - #ifdef _WIN32 -Index: openvswitch-2.17.2/lib/stream-tcp.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-tcp.c -+++ openvswitch-2.17.2/lib/stream-tcp.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "stream.h" -+#include "internal/stream.h" - #include - #include - #include -@@ -26,9 +26,9 @@ - #include - #include - #include "openvswitch/dynamic-string.h" --#include "packets.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - #include "stream-provider.h" - #include "stream-fd.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/lib/stream-unix.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-unix.c -+++ openvswitch-2.17.2/lib/stream-unix.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "stream.h" -+#include "internal/stream.h" - #include - #include - #include -@@ -26,12 +26,12 @@ - #include - #include - #include --#include "ovs-atomic.h" --#include "packets.h" -+#include "openvswitch/ovs-atomic.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "socket-util.h" --#include "dirs.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/dirs.h" -+#include "internal/util.h" - #include "stream-provider.h" - #include "stream-fd.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/lib/stream-windows.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-windows.c -+++ openvswitch-2.17.2/lib/stream-windows.c -@@ -21,9 +21,9 @@ - #include - #include - #include "openvswitch/poll-loop.h" --#include "dirs.h" --#include "fatal-signal.h" --#include "util.h" -+#include "internal/dirs.h" -+#include "internal/fatal-signal.h" -+#include "internal/util.h" - #include "stream-provider.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/lib/stream.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream.c -+++ openvswitch-2.17.2/lib/stream.c -@@ -23,10 +23,10 @@ - #include - #include - #include --#include "coverage.h" --#include "fatal-signal.h" --#include "flow.h" --#include "jsonrpc.h" -+#include "internal/coverage.h" -+#include "internal/fatal-signal.h" -+#include "internal/flow.h" -+#include "internal/jsonrpc.h" - #include "openflow/nicira-ext.h" - #include "openflow/openflow.h" - #include "openvswitch/dynamic-string.h" -@@ -34,12 +34,12 @@ - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" - #include "ovs-replay.h" --#include "ovs-thread.h" --#include "packets.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "random.h" --#include "socket-util.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/socket-util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(stream); - -Index: openvswitch-2.17.2/lib/string.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/string.c -+++ openvswitch-2.17.2/lib/string.c -@@ -18,7 +18,7 @@ - #include - #include - --#include "util.h" -+#include "internal/util.h" - - #ifndef HAVE_STRNLEN - size_t -Index: openvswitch-2.17.2/lib/strsep.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/strsep.c -+++ openvswitch-2.17.2/lib/strsep.c -@@ -28,7 +28,7 @@ - */ - - #include --#include "util.h" -+#include "internal/util.h" - - /* - * Get next token from string *stringp, where tokens are possibly-empty -Index: openvswitch-2.17.2/lib/svec.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/svec.c -+++ openvswitch-2.17.2/lib/svec.c -@@ -15,13 +15,13 @@ - */ - - #include --#include "svec.h" -+#include "internal/svec.h" - #include - #include - #include - #include "openvswitch/dynamic-string.h" --#include "random.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(svec); -Index: openvswitch-2.17.2/lib/syslog-direct.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/syslog-direct.c -+++ openvswitch-2.17.2/lib/syslog-direct.c -@@ -22,9 +22,9 @@ - - #include "openvswitch/compiler.h" - #include "openvswitch/dynamic-string.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - #include "syslog-provider.h" --#include "util.h" -+#include "internal/util.h" - - #define FACILITY_MASK 0x03f8 - -Index: openvswitch-2.17.2/lib/syslog-libc.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/syslog-libc.c -+++ openvswitch-2.17.2/lib/syslog-libc.c -@@ -23,9 +23,9 @@ - - #include "openvswitch/compiler.h" - #include "openvswitch/dynamic-string.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - #include "syslog-provider.h" --#include "util.h" -+#include "internal/util.h" - - - static void syslog_libc_open(struct syslogger *this, int facility); -Index: openvswitch-2.17.2/lib/syslog-null.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/syslog-null.c -+++ openvswitch-2.17.2/lib/syslog-null.c -@@ -19,7 +19,7 @@ - - #include "openvswitch/compiler.h" - #include "syslog-provider.h" --#include "util.h" -+#include "internal/util.h" - - static void syslog_null_open(struct syslogger *this, int facility); - static void syslog_null_log(struct syslogger *this, int pri, const char *msg); -Index: openvswitch-2.17.2/lib/table.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/table.c -+++ openvswitch-2.17.2/lib/table.c -@@ -16,14 +16,14 @@ - - #include - --#include "table.h" -+#include "internal/table.h" - - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "timeval.h" --#include "util.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - struct column { - char *heading; -Index: openvswitch-2.17.2/lib/tc.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/tc.c -+++ openvswitch-2.17.2/lib/tc.c -@@ -35,15 +35,15 @@ - #include - #include - --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "netlink-socket.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/util.h" - #include "openvswitch/vlog.h" --#include "packets.h" --#include "timeval.h" --#include "unaligned.h" -+#include "internal/packets.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" - - #define MAX_PEDIT_OFFSETS 32 - -Index: openvswitch-2.17.2/lib/timer.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/timer.c -+++ openvswitch-2.17.2/lib/timer.c -@@ -16,10 +16,10 @@ - - #include - --#include "timer.h" -+#include "internal/timer.h" - - #include "openvswitch/poll-loop.h" --#include "timeval.h" -+#include "internal/timeval.h" - - /* Returns the number of milliseconds until 'timer' expires. */ - long long int -Index: openvswitch-2.17.2/lib/timeval.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/timeval.c -+++ openvswitch-2.17.2/lib/timeval.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "timeval.h" -+#include "internal/timeval.h" - #include - #include - #include -@@ -25,18 +25,18 @@ - #include - #include - #include --#include "coverage.h" -+#include "internal/coverage.h" - #include "dummy.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" - #include "signals.h" --#include "seq.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/seq.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(timeval); -Index: openvswitch-2.17.2/lib/tnl-neigh-cache.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/tnl-neigh-cache.c -+++ openvswitch-2.17.2/lib/tnl-neigh-cache.c -@@ -24,24 +24,24 @@ - #include - #include - --#include "bitmap.h" --#include "cmap.h" --#include "coverage.h" -+#include "internal/bitmap.h" -+#include "internal/cmap.h" -+#include "internal/coverage.h" - #include "dpif-netdev.h" - #include "openvswitch/dynamic-string.h" - #include "errno.h" --#include "flow.h" --#include "netdev.h" --#include "ovs-atomic.h" --#include "ovs-thread.h" --#include "packets.h" -+#include "internal/flow.h" -+#include "internal/netdev.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" --#include "socket-util.h" --#include "timeval.h" --#include "unaligned.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/seq.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - -Index: openvswitch-2.17.2/lib/tnl-neigh-cache.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/tnl-neigh-cache.h -+++ openvswitch-2.17.2/lib/tnl-neigh-cache.h -@@ -26,10 +26,10 @@ - #include - #include - --#include "flow.h" --#include "netdev.h" --#include "packets.h" --#include "util.h" -+#include "internal/flow.h" -+#include "internal/netdev.h" -+#include "internal/packets.h" -+#include "internal/util.h" - - int tnl_neigh_snoop(const struct flow *flow, struct flow_wildcards *wc, - const char dev_name[IFNAMSIZ], bool allow_update); -Index: openvswitch-2.17.2/lib/tnl-ports.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/tnl-ports.c -+++ openvswitch-2.17.2/lib/tnl-ports.c -@@ -22,16 +22,16 @@ - #include - #include - --#include "classifier.h" -+#include "internal/classifier.h" - #include "openvswitch/dynamic-string.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/list.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "openvswitch/ofpbuf.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "odp-util.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; - static struct classifier cls; /* Tunnel ports. */ -Index: openvswitch-2.17.2/lib/tnl-ports.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/tnl-ports.h -+++ openvswitch-2.17.2/lib/tnl-ports.h -@@ -20,9 +20,9 @@ - #include - #include - --#include "flow.h" --#include "packets.h" --#include "util.h" -+#include "internal/flow.h" -+#include "internal/packets.h" -+#include "internal/util.h" - - odp_port_t tnl_port_map_lookup(struct flow *flow, struct flow_wildcards *wc); - -Index: openvswitch-2.17.2/lib/token-bucket.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/token-bucket.c -+++ openvswitch-2.17.2/lib/token-bucket.c -@@ -20,8 +20,8 @@ - - #include "openvswitch/poll-loop.h" - #include "sat-math.h" --#include "timeval.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - /* Initializes 'tb' to accumulate 'rate' tokens per millisecond, with a - * maximum of 'burst' tokens. -Index: openvswitch-2.17.2/lib/tun-metadata.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/tun-metadata.c -+++ openvswitch-2.17.2/lib/tun-metadata.c -@@ -18,17 +18,17 @@ - #include - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "openvswitch/compiler.h" - #include "openvswitch/hmap.h" - #include "openvswitch/match.h" --#include "nx-match.h" -+#include "internal/nx-match.h" - #include "odp-netlink.h" - #include "openvswitch/ofp-match.h" --#include "ovs-rcu.h" --#include "packets.h" --#include "tun-metadata.h" --#include "util.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/packets.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/util.h" - - struct tun_meta_entry { - struct hmap_node node; /* In struct tun_table's key_hmap. */ -Index: openvswitch-2.17.2/lib/unicode.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/unicode.c -+++ openvswitch-2.17.2/lib/unicode.c -@@ -21,7 +21,7 @@ - #include - - #include "openvswitch/dynamic-string.h" --#include "util.h" -+#include "internal/util.h" - - /* Returns the unicode code point corresponding to leading surrogate 'leading' - * and trailing surrogate 'trailing'. The return value will not make any -Index: openvswitch-2.17.2/lib/unixctl.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/unixctl.c -+++ openvswitch-2.17.2/lib/unixctl.c -@@ -15,20 +15,20 @@ - */ - - #include --#include "unixctl.h" -+#include "internal/unixctl.h" - #include - #include --#include "coverage.h" --#include "dirs.h" -+#include "internal/coverage.h" -+#include "internal/dirs.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include "openvswitch/list.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "stream.h" -+#include "internal/stream.h" - #include "stream-provider.h" --#include "svec.h" -+#include "internal/svec.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(unixctl); -Index: openvswitch-2.17.2/lib/userspace-tso.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/userspace-tso.c -+++ openvswitch-2.17.2/lib/userspace-tso.c -@@ -16,8 +16,8 @@ - - #include - --#include "smap.h" --#include "ovs-thread.h" -+#include "internal/smap.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/vlog.h" - #include "dpdk.h" - #include "userspace-tso.h" -Index: openvswitch-2.17.2/lib/util.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/util.c -+++ openvswitch-2.17.2/lib/util.c -@@ -15,7 +15,7 @@ - */ - - #include --#include "util.h" -+#include "internal/util.h" - #include - #include - #include -@@ -27,13 +27,13 @@ - #include - #include - #include --#include "bitmap.h" --#include "byte-order.h" --#include "coverage.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" --#include "socket-util.h" --#include "timeval.h" -+#include "internal/bitmap.h" -+#include "internal/byte-order.h" -+#include "internal/coverage.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" - #include "openvswitch/vlog.h" - #ifdef HAVE_PTHREAD_SET_NAME_NP - #include -Index: openvswitch-2.17.2/lib/util.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/util.h -+++ openvswitch-2.17.2/lib/util.h -@@ -27,7 +27,6 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "util.h" - #include "openvswitch/util.h" - #if defined(__aarch64__) && __GNUC__ >= 6 - #include -Index: openvswitch-2.17.2/lib/uuid.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/uuid.c -+++ openvswitch-2.17.2/lib/uuid.c -@@ -15,7 +15,7 @@ - - #include - --#include "uuid.h" -+#include "internal/uuid.h" - - #include - #include -@@ -26,13 +26,13 @@ - - #include "aes128.h" - #include "entropy.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/vlog.h" - #include "ovs-replay.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "sha1.h" --#include "timeval.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(uuid); - -Index: openvswitch-2.17.2/lib/vconn-provider.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/vconn-provider.h -+++ openvswitch-2.17.2/lib/vconn-provider.h -@@ -21,7 +21,7 @@ - * OpenFlow device. */ - - #include "openvswitch/vconn.h" --#include "util.h" -+#include "internal/util.h" - #include "openflow/openflow-common.h" - - /* Active virtual connection to an OpenFlow device. */ -Index: openvswitch-2.17.2/lib/vconn-stream.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/vconn-stream.c -+++ openvswitch-2.17.2/lib/vconn-stream.c -@@ -21,13 +21,13 @@ - #include - #include - #include --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/ofpbuf.h" - #include "openflow/openflow.h" - #include "openvswitch/poll-loop.h" --#include "socket-util.h" --#include "stream.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/stream.h" -+#include "internal/util.h" - #include "vconn-provider.h" - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/lib/vconn.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/vconn.c -+++ openvswitch-2.17.2/lib/vconn.c -@@ -23,9 +23,9 @@ - #include - #include - #include --#include "coverage.h" --#include "fatal-signal.h" --#include "flow.h" -+#include "internal/coverage.h" -+#include "internal/fatal-signal.h" -+#include "internal/flow.h" - #include "openflow/nicira-ext.h" - #include "openflow/openflow.h" - #include "openvswitch/dynamic-string.h" -@@ -36,11 +36,11 @@ - #include "openvswitch/ofp-util.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "random.h" --#include "util.h" --#include "socket-util.h" -+#include "internal/random.h" -+#include "internal/util.h" -+#include "internal/socket-util.h" - - VLOG_DEFINE_THIS_MODULE(vconn); - -Index: openvswitch-2.17.2/lib/vl-mff-map.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/vl-mff-map.h -+++ openvswitch-2.17.2/lib/vl-mff-map.h -@@ -17,7 +17,7 @@ - #ifndef VL_MFF_MAP_H - #define VL_MFF_MAP_H 1 - --#include "cmap.h" -+#include "internal/cmap.h" - #include "openvswitch/thread.h" - - /* Variable length mf_fields mapping map. This is a single writer, -Index: openvswitch-2.17.2/lib/vlan-bitmap.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/vlan-bitmap.h -+++ openvswitch-2.17.2/lib/vlan-bitmap.h -@@ -18,7 +18,7 @@ - - #include - #include --#include "bitmap.h" -+#include "internal/bitmap.h" - - /* A "VLAN bitmap" is a 4096-bit bitmap that represents a set. A 1-bit - * indicates that the respective VLAN is a member of the set, a 0-bit indicates -Index: openvswitch-2.17.2/lib/vlog.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/vlog.c -+++ openvswitch-2.17.2/lib/vlog.c -@@ -29,21 +29,21 @@ - #include - #include - #include "async-append.h" --#include "coverage.h" --#include "dirs.h" -+#include "internal/coverage.h" -+#include "internal/dirs.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/ofpbuf.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "sat-math.h" --#include "socket-util.h" --#include "svec.h" -+#include "internal/socket-util.h" -+#include "internal/svec.h" - #include "syslog-direct.h" - #include "syslog-libc.h" - #include "syslog-null.h" - #include "syslog-provider.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(vlog); - -Index: openvswitch-2.17.2/lib/wmi.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/wmi.c -+++ openvswitch-2.17.2/lib/wmi.c -@@ -20,7 +20,7 @@ - #include - #include - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(wmi); - -Index: openvswitch-2.17.2/ofproto/bond.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/bond.c -+++ openvswitch-2.17.2/ofproto/bond.c -@@ -24,12 +24,12 @@ - #include - - #include "connectivity.h" --#include "coverage.h" --#include "dp-packet.h" --#include "flow.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" - #include "openvswitch/hmap.h" - #include "lacp.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "odp-util.h" - #include "ofproto/ofproto-dpif.h" - #include "ofproto/ofproto-dpif-rid.h" -@@ -40,13 +40,13 @@ - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" -+#include "internal/seq.h" - #include "openvswitch/shash.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(bond); - -Index: openvswitch-2.17.2/ofproto/bond.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/bond.h -+++ openvswitch-2.17.2/ofproto/bond.h -@@ -20,7 +20,7 @@ - #include - #include - #include "ofproto-provider.h" --#include "packets.h" -+#include "internal/packets.h" - - struct flow; - struct netdev; -Index: openvswitch-2.17.2/ofproto/bundles.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/bundles.c -+++ openvswitch-2.17.2/ofproto/bundles.c -@@ -19,7 +19,7 @@ - #include - - #include "bundles.h" --#include "coverage.h" -+#include "internal/coverage.h" - #include "fail-open.h" - #include "in-band.h" - #include "odp-util.h" -@@ -33,9 +33,9 @@ - #include "openvswitch/poll-loop.h" - #include "openvswitch/rconn.h" - #include "openvswitch/shash.h" --#include "simap.h" --#include "stream.h" --#include "timeval.h" -+#include "internal/simap.h" -+#include "internal/stream.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(bundles); - -Index: openvswitch-2.17.2/ofproto/bundles.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/bundles.h -+++ openvswitch-2.17.2/ofproto/bundles.h -@@ -24,7 +24,7 @@ - #include "connmgr.h" - #include "ofproto-provider.h" - #include "openvswitch/ofp-msgs.h" --#include "util.h" -+#include "internal/util.h" - - #ifdef __cplusplus - extern "C" { -Index: openvswitch-2.17.2/ofproto/collectors.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/collectors.c -+++ openvswitch-2.17.2/ofproto/collectors.c -@@ -23,9 +23,9 @@ - #include - #include - --#include "socket-util.h" --#include "sset.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/sset.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(collectors); -Index: openvswitch-2.17.2/ofproto/connmgr.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/connmgr.c -+++ openvswitch-2.17.2/ofproto/connmgr.c -@@ -20,7 +20,7 @@ - - #include "bundles.h" - #include "connmgr.h" --#include "coverage.h" -+#include "internal/coverage.h" - #include "fail-open.h" - #include "in-band.h" - #include "odp-util.h" -@@ -32,16 +32,16 @@ - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" --#include "ovs-atomic.h" -+#include "openvswitch/ovs-atomic.h" - #include "pinsched.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/rconn.h" - #include "openvswitch/shash.h" - #include "sat-math.h" --#include "simap.h" --#include "stream.h" --#include "timeval.h" --#include "util.h" -+#include "internal/simap.h" -+#include "internal/stream.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(connmgr); - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); -Index: openvswitch-2.17.2/ofproto/connmgr.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/connmgr.h -+++ openvswitch-2.17.2/ofproto/connmgr.h -@@ -17,7 +17,7 @@ - #ifndef CONNMGR_H - #define CONNMGR_H 1 - --#include "classifier.h" -+#include "internal/classifier.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" - #include "openvswitch/match.h" -Index: openvswitch-2.17.2/ofproto/fail-open.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/fail-open.c -+++ openvswitch-2.17.2/ofproto/fail-open.c -@@ -17,11 +17,11 @@ - #include - #include - #include --#include "classifier.h" -+#include "internal/classifier.h" - #include "connmgr.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "fail-open.h" --#include "flow.h" -+#include "internal/flow.h" - #include "mac-learning.h" - #include "odp-util.h" - #include "openvswitch/ofp-actions.h" -@@ -32,7 +32,7 @@ - #include "ofproto-provider.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/rconn.h" --#include "timeval.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(fail_open); - -Index: openvswitch-2.17.2/ofproto/in-band.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/in-band.c -+++ openvswitch-2.17.2/ofproto/in-band.c -@@ -24,12 +24,12 @@ - #include - #include - #include --#include "classifier.h" --#include "dhcp.h" --#include "flow.h" -+#include "internal/classifier.h" -+#include "internal/dhcp.h" -+#include "internal/flow.h" - #include "in-band.h" --#include "netdev.h" --#include "netlink.h" -+#include "internal/netdev.h" -+#include "internal/netlink.h" - #include "odp-util.h" - #include "ofproto.h" - #include "ofproto-provider.h" -@@ -37,9 +37,9 @@ - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "timeval.h" -+#include "internal/timeval.h" - - VLOG_DEFINE_THIS_MODULE(in_band); - -Index: openvswitch-2.17.2/ofproto/in-band.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/in-band.h -+++ openvswitch-2.17.2/ofproto/in-band.h -@@ -22,7 +22,7 @@ - #include - #include - #include --#include "flow.h" -+#include "internal/flow.h" - - struct flow; - struct in_band; -Index: openvswitch-2.17.2/ofproto/netflow.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/netflow.c -+++ openvswitch-2.17.2/ofproto/netflow.c -@@ -22,19 +22,19 @@ - #include - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "collectors.h" - #include "dpif.h" --#include "flow.h" -+#include "internal/flow.h" - #include "lib/netflow.h" - #include "openvswitch/ofpbuf.h" - #include "ofproto.h" - #include "ofproto/netflow.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "socket-util.h" --#include "timeval.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(netflow); -Index: openvswitch-2.17.2/ofproto/netflow.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/netflow.h -+++ openvswitch-2.17.2/ofproto/netflow.h -@@ -18,8 +18,8 @@ - #define OFPROTO_NETFLOW_H 1 - - #include --#include "flow.h" --#include "sset.h" -+#include "internal/flow.h" -+#include "internal/sset.h" - - /* Default active timeout interval, in seconds. - * -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-ipfix.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-ipfix.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-ipfix.c -@@ -17,23 +17,23 @@ - #include - #include "ofproto-dpif-ipfix.h" - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "collectors.h" --#include "flow.h" --#include "hash.h" -+#include "internal/flow.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "openvswitch/list.h" - #include "openvswitch/ofp-ipfix.h" - #include "openvswitch/ofpbuf.h" - #include "ofproto.h" - #include "ofproto-dpif.h" --#include "dp-packet.h" --#include "packets.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "sset.h" --#include "util.h" --#include "timeval.h" -+#include "internal/sset.h" -+#include "internal/util.h" -+#include "internal/timeval.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ipfix); -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-mirror.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-mirror.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-mirror.c -@@ -18,8 +18,8 @@ - - #include - --#include "cmap.h" --#include "hmapx.h" -+#include "internal/cmap.h" -+#include "internal/hmapx.h" - #include "ofproto.h" - #include "vlan-bitmap.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-mirror.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-mirror.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-mirror.h -@@ -17,7 +17,7 @@ - - #include - --#include "util.h" -+#include "internal/util.h" - - #define MAX_MIRRORS 32 - typedef uint32_t mirror_mask_t; -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-monitor.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-monitor.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-monitor.c -@@ -21,20 +21,20 @@ - - #include "bfd.h" - #include "cfm.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "guarded-list.h" --#include "hash.h" -+#include "internal/hash.h" - #include "heap.h" - #include "openvswitch/hmap.h" --#include "latch.h" -+#include "internal/latch.h" - #include "openvswitch/ofpbuf.h" - #include "ofproto-dpif.h" - #include "ovs-lldp.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" --#include "timeval.h" --#include "util.h" -+#include "internal/seq.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ofproto_dpif_monitor); -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-monitor.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-monitor.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-monitor.h -@@ -18,7 +18,7 @@ - #include - - #include "openflow/openflow.h" --#include "packets.h" -+#include "internal/packets.h" - - struct bfd; - struct cfm; -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-rid.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-rid.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-rid.h -@@ -20,13 +20,13 @@ - #include - #include - --#include "cmap.h" -+#include "internal/cmap.h" - #include "ofproto-dpif-mirror.h" - #include "ofproto/ofproto-provider.h" - #include "openvswitch/list.h" - #include "openvswitch/ofp-actions.h" --#include "ovs-thread.h" --#include "uuid.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/uuid.h" - - struct ofproto_dpif; - struct rule; -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-sflow.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-sflow.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-sflow.c -@@ -25,22 +25,22 @@ - #include "collectors.h" - #include "openvswitch/compiler.h" - #include "dpif.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "netdev.h" --#include "netlink.h" -+#include "internal/netdev.h" -+#include "internal/netlink.h" - #include "openvswitch/ofpbuf.h" - #include "ofproto.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" - #include "ovs-router.h" - #include "route-table.h" - #include "sflow_api.h" --#include "socket-util.h" --#include "timeval.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" - #include "openvswitch/vlog.h" - #include "lib/odp-util.h" --#include "lib/unaligned.h" -+#include "internal/unaligned.h" - #include "ofproto-provider.h" - #include "lacp.h" - -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-sflow.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-sflow.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-sflow.h -@@ -19,7 +19,7 @@ - #define OFPROTO_DPIF_SFLOW_H 1 - - #include --#include "svec.h" -+#include "internal/svec.h" - #include "lib/odp-util.h" - - struct dpif; -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-trace.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-trace.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-trace.c -@@ -21,7 +21,7 @@ - #include "conntrack.h" - #include "dpif.h" - #include "ofproto-dpif-xlate.h" --#include "unixctl.h" -+#include "internal/unixctl.h" - - static void oftrace_node_destroy(struct oftrace_node *); - -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-trace.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-trace.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-trace.h -@@ -32,7 +32,7 @@ - #include "ofproto/ofproto-dpif.h" - #include "openvswitch/compiler.h" - #include "openvswitch/list.h" --#include "flow.h" -+#include "internal/flow.h" - - /* Type of a node within a trace. */ - enum oftrace_node_type { -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-upcall.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-upcall.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-upcall.c -@@ -20,28 +20,28 @@ - #include - - #include "connmgr.h" --#include "coverage.h" --#include "cmap.h" -+#include "internal/coverage.h" -+#include "internal/cmap.h" - #include "lib/dpif-provider.h" - #include "dpif.h" - #include "openvswitch/dynamic-string.h" - #include "fail-open.h" - #include "guarded-list.h" --#include "latch.h" -+#include "internal/latch.h" - #include "openvswitch/list.h" --#include "netlink.h" -+#include "internal/netlink.h" - #include "openvswitch/ofpbuf.h" - #include "ofproto-dpif-ipfix.h" - #include "ofproto-dpif-sflow.h" - #include "ofproto-dpif-xlate.h" - #include "ofproto-dpif-xlate-cache.h" - #include "ofproto-dpif-trace.h" --#include "ovs-rcu.h" --#include "packets.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" -+#include "internal/seq.h" - #include "tunnel.h" --#include "unixctl.h" -+#include "internal/unixctl.h" - #include "openvswitch/vlog.h" - #include "lib/netdev-provider.h" - -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-xlate-cache.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-xlate-cache.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-xlate-cache.c -@@ -24,13 +24,13 @@ - #include - - #include "bfd.h" --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "bond.h" --#include "bundle.h" --#include "byte-order.h" -+#include "internal/bundle.h" -+#include "internal/byte-order.h" - #include "connmgr.h" --#include "coverage.h" --#include "dp-packet.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" - #include "dpif.h" - #include "learn.h" - #include "mac-learning.h" -@@ -42,9 +42,9 @@ - #include "openvswitch/dynamic-string.h" - #include "openvswitch/vlog.h" - #include "ovs-router.h" --#include "packets.h" -+#include "internal/packets.h" - #include "tnl-neigh-cache.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofproto_xlate_cache); - -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-xlate-cache.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-xlate-cache.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-xlate-cache.h -@@ -21,7 +21,7 @@ - #include - - #include "openvswitch/types.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "odp-util.h" - #include "ofproto/ofproto-dpif-mirror.h" - #include "openvswitch/ofpbuf.h" -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-xlate.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-xlate.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-xlate.c -@@ -24,25 +24,25 @@ - #include - - #include "bfd.h" --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "bond.h" --#include "bundle.h" --#include "byte-order.h" -+#include "internal/bundle.h" -+#include "internal/byte-order.h" - #include "cfm.h" - #include "connmgr.h" --#include "coverage.h" --#include "csum.h" --#include "dp-packet.h" -+#include "internal/coverage.h" -+#include "internal/csum.h" -+#include "internal/dp-packet.h" - #include "dpif.h" - #include "in-band.h" - #include "lacp.h" - #include "learn.h" - #include "mac-learning.h" --#include "mcast-snooping.h" -+#include "internal/mcast-snooping.h" - #include "multipath.h" - #include "netdev-vport.h" --#include "netlink.h" --#include "nx-match.h" -+#include "internal/netlink.h" -+#include "internal/nx-match.h" - #include "odp-execute.h" - #include "ofproto/ofproto-dpif-ipfix.h" - #include "ofproto/ofproto-dpif-mirror.h" -@@ -60,12 +60,12 @@ - #include "openvswitch/vlog.h" - #include "ovs-lldp.h" - #include "ovs-router.h" --#include "packets.h" -+#include "internal/packets.h" - #include "tnl-neigh-cache.h" - #include "tnl-ports.h" - #include "tunnel.h" --#include "util.h" --#include "uuid.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - COVERAGE_DEFINE(xlate_actions); - COVERAGE_DEFINE(xlate_actions_oversize); -Index: openvswitch-2.17.2/ofproto/ofproto-dpif-xlate.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif-xlate.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif-xlate.h -@@ -15,8 +15,8 @@ - #ifndef OFPROTO_DPIF_XLATE_H - #define OFPROTO_DPIF_XLATE_H 1 - --#include "dp-packet.h" --#include "flow.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" - #include "openvswitch/meta-flow.h" - #include "odp-util.h" - #include "openvswitch/ofpbuf.h" -@@ -26,7 +26,7 @@ - #include "ofproto.h" - #include "stp.h" - #include "ovs-lldp.h" --#include "uuid.h" -+#include "internal/uuid.h" - - struct bfd; - struct bond; -Index: openvswitch-2.17.2/ofproto/ofproto-dpif.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif.c -+++ openvswitch-2.17.2/ofproto/ofproto-dpif.c -@@ -18,26 +18,26 @@ - - #include "bfd.h" - #include "bond.h" --#include "bundle.h" --#include "byte-order.h" -+#include "internal/bundle.h" -+#include "internal/byte-order.h" - #include "connectivity.h" - #include "connmgr.h" --#include "coverage.h" -+#include "internal/coverage.h" - #include "cfm.h" - #include "ct-dpif.h" - #include "fail-open.h" - #include "guarded-list.h" --#include "hmapx.h" -+#include "internal/hmapx.h" - #include "lacp.h" - #include "learn.h" - #include "mac-learning.h" - #include "math.h" --#include "mcast-snooping.h" -+#include "internal/mcast-snooping.h" - #include "multipath.h" - #include "netdev-vport.h" --#include "netdev.h" --#include "netlink.h" --#include "nx-match.h" -+#include "internal/netdev.h" -+#include "internal/netlink.h" -+#include "internal/nx-match.h" - #include "odp-util.h" - #include "odp-execute.h" - #include "ofproto/ofproto-dpif.h" -@@ -59,18 +59,18 @@ - #include "openvswitch/uuid.h" - #include "openvswitch/vlog.h" - #include "ovs-lldp.h" --#include "ovs-rcu.h" -+#include "openvswitch/ovs-rcu.h" - #include "ovs-router.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" --#include "simap.h" --#include "smap.h" --#include "timer.h" -+#include "internal/seq.h" -+#include "internal/simap.h" -+#include "internal/smap.h" -+#include "internal/timer.h" - #include "tunnel.h" --#include "unaligned.h" --#include "unixctl.h" --#include "util.h" --#include "uuid.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - #include "vlan-bitmap.h" - - VLOG_DEFINE_THIS_MODULE(ofproto_dpif); -Index: openvswitch-2.17.2/ofproto/ofproto-dpif.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-dpif.h -+++ openvswitch-2.17.2/ofproto/ofproto-dpif.h -@@ -48,12 +48,12 @@ - - #include "dpif.h" - #include "fail-open.h" --#include "hmapx.h" -+#include "internal/hmapx.h" - #include "odp-util.h" --#include "id-pool.h" --#include "ovs-thread.h" -+#include "internal/id-pool.h" -+#include "openvswitch/ovs-thread.h" - #include "ofproto-provider.h" --#include "util.h" -+#include "internal/util.h" - - struct dpif_flow_stats; - struct ofproto_async_msg; -Index: openvswitch-2.17.2/ofproto/ofproto-provider.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto-provider.h -+++ openvswitch-2.17.2/ofproto/ofproto-provider.h -@@ -34,10 +34,10 @@ - */ - - #include "cfm.h" --#include "classifier.h" -+#include "internal/classifier.h" - #include "guarded-list.h" - #include "heap.h" --#include "hindex.h" -+#include "internal/hindex.h" - #include "object-collection.h" - #include "ofproto/ofproto.h" - #include "openvswitch/list.h" -@@ -49,14 +49,14 @@ - #include "openvswitch/ofp-port.h" - #include "openvswitch/ofp-switch.h" - #include "openvswitch/ofp-table.h" --#include "ovs-atomic.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/shash.h" --#include "simap.h" --#include "timeval.h" --#include "tun-metadata.h" --#include "versions.h" -+#include "internal/simap.h" -+#include "internal/timeval.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/versions.h" - #include "vl-mff-map.h" - - struct match; -Index: openvswitch-2.17.2/ofproto/ofproto.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto.c -+++ openvswitch-2.17.2/ofproto/ofproto.c -@@ -22,18 +22,18 @@ - #include - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "bundles.h" --#include "byte-order.h" --#include "classifier.h" -+#include "internal/byte-order.h" -+#include "internal/classifier.h" - #include "connectivity.h" - #include "connmgr.h" --#include "coverage.h" --#include "dp-packet.h" --#include "hash.h" -+#include "internal/coverage.h" -+#include "internal/dp-packet.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "netdev.h" --#include "nx-match.h" -+#include "internal/netdev.h" -+#include "internal/nx-match.h" - #include "ofproto.h" - #include "ofproto-provider.h" - #include "openflow/nicira-ext.h" -@@ -51,21 +51,21 @@ - #include "openvswitch/ofp-util.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "ovs-rcu.h" --#include "packets.h" -+#include "openvswitch/ovs-rcu.h" -+#include "internal/packets.h" - #include "pinsched.h" - #include "openvswitch/poll-loop.h" --#include "random.h" --#include "seq.h" -+#include "internal/random.h" -+#include "internal/seq.h" - #include "openvswitch/shash.h" --#include "simap.h" --#include "smap.h" --#include "sset.h" --#include "timeval.h" --#include "tun-metadata.h" --#include "unaligned.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/simap.h" -+#include "internal/smap.h" -+#include "internal/sset.h" -+#include "internal/timeval.h" -+#include "internal/tun-metadata-private.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofproto); - -Index: openvswitch-2.17.2/ofproto/ofproto.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/ofproto.h -+++ openvswitch-2.17.2/ofproto/ofproto.h -@@ -23,13 +23,13 @@ - #include - #include - #include "cfm.h" --#include "classifier.h" --#include "flow.h" -+#include "internal/classifier.h" -+#include "internal/flow.h" - #include "openvswitch/meta-flow.h" - #include "netflow.h" - #include "rstp.h" --#include "smap.h" --#include "sset.h" -+#include "internal/smap.h" -+#include "internal/sset.h" - #include "stp.h" - #include "lacp.h" - -Index: openvswitch-2.17.2/ofproto/pinsched.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/pinsched.c -+++ openvswitch-2.17.2/ofproto/pinsched.c -@@ -21,16 +21,16 @@ - #include - #include - #include --#include "flow.h" --#include "hash.h" -+#include "internal/flow.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "openvswitch/ofpbuf.h" - #include "openflow/openflow.h" - #include "openvswitch/poll-loop.h" --#include "random.h" -+#include "internal/random.h" - #include "openvswitch/rconn.h" - #include "sat-math.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "openvswitch/token-bucket.h" - #include "openvswitch/vconn.h" - -Index: openvswitch-2.17.2/ofproto/pinsched.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/pinsched.h -+++ openvswitch-2.17.2/ofproto/pinsched.h -@@ -18,7 +18,7 @@ - #define PINSCHED_H_H 1 - - #include --#include "flow.h" -+#include "internal/flow.h" - - struct ovs_list; - struct ofpbuf; -Index: openvswitch-2.17.2/ofproto/tunnel.c -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/tunnel.c -+++ openvswitch-2.17.2/ofproto/tunnel.c -@@ -15,27 +15,27 @@ - #include - #include - --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "connectivity.h" --#include "csum.h" -+#include "internal/csum.h" - #include "dpif.h" - #include "openvswitch/dynamic-string.h" - #include "fat-rwlock.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "netdev.h" -+#include "internal/netdev.h" - #include "odp-util.h" - #include "openvswitch/ofpbuf.h" --#include "packets.h" -+#include "internal/packets.h" - #include "route-table.h" --#include "seq.h" --#include "smap.h" --#include "socket-util.h" -+#include "internal/seq.h" -+#include "internal/smap.h" -+#include "internal/socket-util.h" - #include "tnl-ports.h" - #include "tunnel.h" - #include "openvswitch/vlog.h" --#include "unaligned.h" --#include "unixctl.h" -+#include "internal/unaligned.h" -+#include "internal/unixctl.h" - #include "ofproto-dpif.h" - #include "netdev-vport.h" - -Index: openvswitch-2.17.2/ofproto/tunnel.h -=================================================================== ---- openvswitch-2.17.2.orig/ofproto/tunnel.h -+++ openvswitch-2.17.2/ofproto/tunnel.h -@@ -18,7 +18,7 @@ - - #include - #include --#include "flow.h" -+#include "internal/flow.h" - - /* Tunnel port emulation layer. - * -Index: openvswitch-2.17.2/ovsdb/column.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/column.c -+++ openvswitch-2.17.2/ovsdb/column.c -@@ -22,10 +22,10 @@ - #include "column.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "table.h" --#include "util.h" -+#include "internal/util.h" - - struct ovsdb_column * - ovsdb_column_create(const char *name, -Index: openvswitch-2.17.2/ovsdb/column.h -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/column.h -+++ openvswitch-2.17.2/ovsdb/column.h -@@ -18,7 +18,7 @@ - - #include - #include "openvswitch/compiler.h" --#include "ovsdb-types.h" -+#include "openvswitch/ovsdb-types.h" - - struct ovsdb_table; - struct ovsdb_table_schema; -Index: openvswitch-2.17.2/ovsdb/condition.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/condition.c -+++ openvswitch-2.17.2/ovsdb/condition.c -@@ -21,13 +21,13 @@ - - #include "column.h" - #include "openvswitch/json.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "row.h" - - #include - - #include "table.h" --#include "util.h" -+#include "internal/util.h" - - static struct ovsdb_error * - ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, -Index: openvswitch-2.17.2/ovsdb/condition.h -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/condition.h -+++ openvswitch-2.17.2/ovsdb/condition.h -@@ -18,9 +18,9 @@ - - #include - #include "openvswitch/compiler.h" --#include "ovsdb-data.h" --#include "bitmap.h" --#include "ovsdb-condition.h" -+#include "openvswitch/ovsdb-data.h" -+#include "internal/bitmap.h" -+#include "openvswitch/ovsdb-condition.h" - - struct json; - struct ovsdb_table_schema; -Index: openvswitch-2.17.2/ovsdb/execution.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/execution.c -+++ openvswitch-2.17.2/ovsdb/execution.c -@@ -24,15 +24,15 @@ - #include "file.h" - #include "openvswitch/json.h" - #include "mutation.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "query.h" - #include "rbac.h" - #include "row.h" - #include "server.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" - - struct ovsdb_execution { -Index: openvswitch-2.17.2/ovsdb/file.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/file.c -+++ openvswitch-2.17.2/ovsdb/file.c -@@ -21,22 +21,22 @@ - #include - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "column.h" - #include "log.h" - #include "openvswitch/json.h" - #include "lockfile.h" - #include "ovsdb.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "row.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - #include "storage.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" --#include "unixctl.h" --#include "uuid.h" --#include "util.h" -+#include "internal/unixctl.h" -+#include "internal/uuid.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_file); -Index: openvswitch-2.17.2/ovsdb/jsonrpc-server.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/jsonrpc-server.c -+++ openvswitch-2.17.2/ovsdb/jsonrpc-server.c -@@ -19,28 +19,28 @@ - - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "column.h" - #include "openvswitch/dynamic-string.h" - #include "monitor.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "internal/jsonrpc.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "ovsdb.h" - #include "condition.h" - #include "openvswitch/poll-loop.h" - #include "reconnect.h" - #include "row.h" - #include "server.h" --#include "simap.h" -+#include "internal/simap.h" - #include "storage.h" --#include "stream.h" -+#include "internal/stream.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" - #include "trigger.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_jsonrpc_server); -Index: openvswitch-2.17.2/ovsdb/log.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/log.c -+++ openvswitch-2.17.2/ovsdb/log.c -@@ -28,17 +28,17 @@ - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" - #include "openvswitch/vlog.h" --#include "ovs-atomic.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" -+#include "openvswitch/ovsdb-error.h" - #include "ovsdb.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" -+#include "internal/seq.h" - #include "sha1.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - #include "transaction.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_log); - -Index: openvswitch-2.17.2/ovsdb/monitor.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/monitor.c -+++ openvswitch-2.17.2/ovsdb/monitor.c -@@ -18,24 +18,24 @@ - - #include - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "column.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "internal/jsonrpc.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "ovsdb.h" - #include "row.h" - #include "condition.h" --#include "simap.h" --#include "hash.h" -+#include "internal/simap.h" -+#include "internal/hash.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" - #include "jsonrpc-server.h" - #include "monitor.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_monitor); -Index: openvswitch-2.17.2/ovsdb/mutation.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/mutation.c -+++ openvswitch-2.17.2/ovsdb/mutation.c -@@ -21,14 +21,14 @@ - #include - - #include "column.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "openvswitch/json.h" - #include "row.h" - - #include - - #include "table.h" --#include "util.h" -+#include "internal/util.h" - - struct ovsdb_error * - ovsdb_mutator_from_string(const char *name, enum ovsdb_mutator *mutator) -Index: openvswitch-2.17.2/ovsdb/mutation.h -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/mutation.h -+++ openvswitch-2.17.2/ovsdb/mutation.h -@@ -18,7 +18,7 @@ - - #include - #include "openvswitch/compiler.h" --#include "ovsdb-data.h" -+#include "openvswitch/ovsdb-data.h" - - struct json; - struct ovsdb_table_schema; -Index: openvswitch-2.17.2/ovsdb/ovsdb-client.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/ovsdb-client.c -+++ openvswitch-2.17.2/ovsdb/ovsdb-client.c -@@ -26,37 +26,37 @@ - #include - #include - --#include "command-line.h" -+#include "internal/command-line.h" - #include "column.h" - #include "openvswitch/compiler.h" --#include "daemon.h" --#include "dirs.h" -+#include "internal/daemon.h" -+#include "internal/dirs.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "file.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" --#include "lib/table.h" -+#include "internal/jsonrpc.h" -+#include "internal/table.h" - #include "log.h" - #include "ovs-replay.h" - #include "ovsdb.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" - #include "ovsdb-session.h" - #include "openvswitch/poll-loop.h" - #include "row.h" --#include "sort.h" --#include "svec.h" -+#include "internal/sort.h" -+#include "internal/svec.h" - #include "storage.h" --#include "stream.h" --#include "stream-ssl.h" -+#include "internal/stream.h" -+#include "internal/stream-ssl.h" - #include "table.h" - #include "transaction.h" - #include "monitor.h" - #include "condition.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_client); -Index: openvswitch-2.17.2/ovsdb/ovsdb-idlc.in -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/ovsdb-idlc.in -+++ openvswitch-2.17.2/ovsdb/ovsdb-idlc.in -@@ -193,10 +193,10 @@ def printCIDLHeader(schemaFile): - #include - #include - #include "openvswitch/json.h" --#include "ovsdb-data.h" --#include "ovsdb-idl-provider.h" --#include "smap.h" --#include "uuid.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-idl-provider.h" -+#include "internal/smap.h" -+#include "internal/uuid.h" - - #ifdef __cplusplus - extern "C" { -@@ -484,10 +484,10 @@ def printCIDLSource(schemaFile): - #include - #include %(header)s - #include --#include "ovs-thread.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "internal/util.h" - - %(cDecls)s - -Index: openvswitch-2.17.2/ovsdb/ovsdb-server.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/ovsdb-server.c -+++ openvswitch-2.17.2/ovsdb/ovsdb-server.c -@@ -23,42 +23,42 @@ - #include - - #include "column.h" --#include "command-line.h" --#include "daemon.h" --#include "dirs.h" -+#include "internal/command-line.h" -+#include "internal/daemon.h" -+#include "internal/dirs.h" - #include "dns-resolve.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "file.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include "jsonrpc-server.h" - #include "openvswitch/list.h" --#include "memory.h" -+#include "internal/memory.h" - #include "monitor.h" - #include "ovs-replay.h" - #include "ovsdb.h" --#include "ovsdb-data.h" --#include "ovsdb-types.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-types.h" -+#include "openvswitch/ovsdb-error.h" - #include "openvswitch/poll-loop.h" --#include "process.h" -+#include "internal/process.h" - #include "replication.h" - #include "relay.h" - #include "row.h" --#include "simap.h" -+#include "internal/simap.h" - #include "openvswitch/shash.h" --#include "stream-ssl.h" --#include "stream.h" --#include "sset.h" -+#include "internal/stream-ssl.h" -+#include "internal/stream.h" -+#include "internal/sset.h" - #include "storage.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" - #include "trigger.h" --#include "util.h" --#include "unixctl.h" -+#include "internal/util.h" -+#include "internal/unixctl.h" - #include "perf-counter.h" - #include "ovsdb-util.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/ovsdb/ovsdb-tool.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/ovsdb-tool.c -+++ openvswitch-2.17.2/ovsdb/ovsdb-tool.c -@@ -23,29 +23,30 @@ - #include - - #include "column.h" -+#include "internal/command-line.h" - #include "openvswitch/compiler.h" --#include "dirs.h" -+#include "internal/dirs.h" - #include "openvswitch/dynamic-string.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "file.h" --#include "hash.h" -+#include "internal/hash.h" - #include "lockfile.h" - #include "log.h" - #include "openvswitch/hmap.h" - #include "openvswitch/json.h" - #include "ovsdb.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "raft.h" - #include "raft-private.h" --#include "smap.h" --#include "socket-util.h" -+#include "internal/smap.h" -+#include "internal/socket-util.h" - #include "storage.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - /* -m, --more: Verbosity level for "show-log" command output. */ -Index: openvswitch-2.17.2/ovsdb/ovsdb-util.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/ovsdb-util.c -+++ openvswitch-2.17.2/ovsdb/ovsdb-util.c -@@ -15,7 +15,7 @@ - - #include - #include "row.h" --#include "sset.h" -+#include "internal/sset.h" - #include "table.h" - #include "ovsdb-util.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/ovsdb/ovsdb.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/ovsdb.c -+++ openvswitch-2.17.2/ovsdb/ovsdb.c -@@ -25,13 +25,13 @@ - #include "file.h" - #include "monitor.h" - #include "openvswitch/json.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" --#include "ovsdb-types.h" --#include "simap.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" -+#include "openvswitch/ovsdb-types.h" -+#include "internal/simap.h" - #include "storage.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" - #include "transaction-forward.h" - #include "trigger.h" -Index: openvswitch-2.17.2/ovsdb/raft-private.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/raft-private.c -+++ openvswitch-2.17.2/ovsdb/raft-private.c -@@ -18,12 +18,12 @@ - - #include "raft-private.h" - --#include "coverage.h" -+#include "internal/coverage.h" - #include "openvswitch/dynamic-string.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" --#include "socket-util.h" --#include "sset.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" -+#include "internal/socket-util.h" -+#include "internal/sset.h" - - COVERAGE_DEFINE(raft_entry_serialize); - -Index: openvswitch-2.17.2/ovsdb/raft-private.h -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/raft-private.h -+++ openvswitch-2.17.2/ovsdb/raft-private.h -@@ -23,7 +23,7 @@ - #include - #include "openvswitch/hmap.h" - #include "openvswitch/uuid.h" --#include "sset.h" -+#include "internal/sset.h" - - struct ds; - struct ovsdb_parser; -Index: openvswitch-2.17.2/ovsdb/raft-rpc.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/raft-rpc.c -+++ openvswitch-2.17.2/ovsdb/raft-rpc.c -@@ -20,13 +20,13 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "jsonrpc.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "internal/jsonrpc.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" - #include "openvswitch/vlog.h" --#include "sset.h" -+#include "internal/sset.h" - - VLOG_DEFINE_THIS_MODULE(raft_rpc); - -Index: openvswitch-2.17.2/ovsdb/raft-rpc.h -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/raft-rpc.h -+++ openvswitch-2.17.2/ovsdb/raft-rpc.h -@@ -24,7 +24,7 @@ - #include "openvswitch/uuid.h" - #include "raft.h" - #include "raft-private.h" --#include "sset.h" -+#include "internal/sset.h" - - struct ds; - -Index: openvswitch-2.17.2/ovsdb/raft.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/raft.c -+++ openvswitch-2.17.2/ovsdb/raft.c -@@ -22,8 +22,8 @@ - #include - #include - --#include "hash.h" --#include "jsonrpc.h" -+#include "internal/hash.h" -+#include "internal/jsonrpc.h" - #include "lockfile.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/hmap.h" -@@ -31,19 +31,19 @@ - #include "openvswitch/list.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "ovsdb/log.h" - #include "raft-rpc.h" --#include "random.h" --#include "simap.h" --#include "socket-util.h" --#include "stream.h" --#include "timeval.h" -+#include "internal/random.h" -+#include "internal/simap.h" -+#include "internal/socket-util.h" -+#include "internal/stream.h" -+#include "internal/timeval.h" - #include "unicode.h" --#include "unixctl.h" --#include "util.h" --#include "uuid.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(raft); - -Index: openvswitch-2.17.2/ovsdb/raft.h -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/raft.h -+++ openvswitch-2.17.2/ovsdb/raft.h -@@ -62,7 +62,7 @@ - #include - #include - #include "openvswitch/compiler.h" --#include "uuid.h" -+#include "internal/uuid.h" - - struct json; - struct ovsdb_log; -Index: openvswitch-2.17.2/ovsdb/rbac.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/rbac.c -+++ openvswitch-2.17.2/ovsdb/rbac.c -@@ -24,16 +24,16 @@ - #include "file.h" - #include "mutation.h" - #include "openvswitch/vlog.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" - #include "ovsdb-util.h" - #include "ovsdb.h" - #include "query.h" - #include "row.h" - #include "server.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" - - VLOG_DEFINE_THIS_MODULE(ovsdb_rbac); -Index: openvswitch-2.17.2/ovsdb/relay.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/relay.c -+++ openvswitch-2.17.2/ovsdb/relay.c -@@ -18,8 +18,8 @@ - - #include "relay.h" - --#include "coverage.h" --#include "jsonrpc.h" -+#include "internal/coverage.h" -+#include "internal/jsonrpc.h" - #include "openvswitch/hmap.h" - #include "openvswitch/json.h" - #include "openvswitch/list.h" -@@ -27,14 +27,14 @@ - #include "openvswitch/shash.h" - #include "openvswitch/vlog.h" - #include "ovsdb.h" --#include "ovsdb-cs.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-cs.h" -+#include "openvswitch/ovsdb-error.h" - #include "row.h" - #include "table.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "transaction.h" - #include "transaction-forward.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(relay); - -Index: openvswitch-2.17.2/ovsdb/replication.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/replication.c -+++ openvswitch-2.17.2/ovsdb/replication.c -@@ -19,22 +19,22 @@ - - - #include "condition.h" --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/hmap.h" - #include "openvswitch/json.h" - #include "openvswitch/vlog.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "ovsdb.h" - #include "query.h" - #include "replication.h" - #include "row.h" --#include "sset.h" --#include "stream.h" --#include "svec.h" -+#include "internal/sset.h" -+#include "internal/stream.h" -+#include "internal/svec.h" - #include "table.h" - #include "transaction.h" --#include "uuid.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(replication); - -Index: openvswitch-2.17.2/ovsdb/row.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/row.c -+++ openvswitch-2.17.2/ovsdb/row.c -@@ -21,11 +21,11 @@ - - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "openvswitch/shash.h" --#include "sort.h" -+#include "internal/sort.h" - #include "table.h" --#include "util.h" -+#include "internal/util.h" - - static struct ovsdb_row * - allocate_row(const struct ovsdb_table *table) -Index: openvswitch-2.17.2/ovsdb/row.h -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/row.h -+++ openvswitch-2.17.2/ovsdb/row.h -@@ -21,7 +21,7 @@ - #include "column.h" - #include "openvswitch/hmap.h" - #include "openvswitch/list.h" --#include "ovsdb-data.h" -+#include "openvswitch/ovsdb-data.h" - - struct ovsdb_column_set; - -Index: openvswitch-2.17.2/ovsdb/server.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/server.c -+++ openvswitch-2.17.2/ovsdb/server.c -@@ -17,9 +17,9 @@ - - #include "server.h" - --#include "hash.h" -+#include "internal/hash.h" - #include "ovsdb.h" --#include "uuid.h" -+#include "internal/uuid.h" - - /* Initializes 'session' as a session within 'server'. */ - void -Index: openvswitch-2.17.2/ovsdb/storage.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/storage.c -+++ openvswitch-2.17.2/ovsdb/storage.c -@@ -19,16 +19,16 @@ - #include "storage.h" - #include - #include "log.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "openvswitch/json.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" - #include "ovsdb.h" - #include "raft.h" --#include "random.h" --#include "simap.h" --#include "timeval.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/simap.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(storage); - -Index: openvswitch-2.17.2/ovsdb/table.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/table.c -+++ openvswitch-2.17.2/ovsdb/table.c -@@ -21,9 +21,9 @@ - - #include "openvswitch/json.h" - #include "column.h" --#include "ovsdb-error.h" --#include "ovsdb-parser.h" --#include "ovsdb-types.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-parser.h" -+#include "openvswitch/ovsdb-types.h" - #include "row.h" - #include "transaction.h" - -Index: openvswitch-2.17.2/ovsdb/transaction-forward.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/transaction-forward.c -+++ openvswitch-2.17.2/ovsdb/transaction-forward.c -@@ -18,16 +18,16 @@ - - #include "transaction-forward.h" - --#include "coverage.h" --#include "jsonrpc.h" -+#include "internal/coverage.h" -+#include "internal/jsonrpc.h" - #include "openvswitch/hmap.h" - #include "openvswitch/json.h" - #include "openvswitch/list.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" - #include "ovsdb.h" --#include "ovsdb-cs.h" --#include "util.h" -+#include "openvswitch/ovsdb-cs.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(transaction_forward); - -Index: openvswitch-2.17.2/ovsdb/transaction.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/transaction.c -+++ openvswitch-2.17.2/ovsdb/transaction.c -@@ -17,22 +17,22 @@ - - #include "transaction.h" - --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "openvswitch/dynamic-string.h" - #include "file.h" --#include "hash.h" -+#include "internal/hash.h" - #include "monitor.h" - #include "openvswitch/hmap.h" - #include "openvswitch/json.h" - #include "openvswitch/list.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vlog.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "ovsdb.h" - #include "row.h" - #include "storage.h" - #include "table.h" --#include "uuid.h" -+#include "internal/uuid.h" - - VLOG_DEFINE_THIS_MODULE(transaction); - -Index: openvswitch-2.17.2/ovsdb/trigger.c -=================================================================== ---- openvswitch-2.17.2.orig/ovsdb/trigger.c -+++ openvswitch-2.17.2/ovsdb/trigger.c -@@ -22,15 +22,15 @@ - - #include "file.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include "ovsdb.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "openvswitch/poll-loop.h" - #include "server.h" - #include "transaction.h" - #include "transaction-forward.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(trigger); - -Index: openvswitch-2.17.2/tests/oss-fuzz/flow_extract_target.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/oss-fuzz/flow_extract_target.c -+++ openvswitch-2.17.2/tests/oss-fuzz/flow_extract_target.c -@@ -1,9 +1,9 @@ - #include --#include "classifier.h" -+#include "internal/classifier.h" - #include - #include "fuzzer.h" --#include "dp-packet.h" --#include "flow.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" - #include "openvswitch/ofp-match.h" - #include "openvswitch/ofp-print.h" - #include "openvswitch/match.h" -Index: openvswitch-2.17.2/tests/oss-fuzz/json_parser_target.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/oss-fuzz/json_parser_target.c -+++ openvswitch-2.17.2/tests/oss-fuzz/json_parser_target.c -@@ -1,8 +1,8 @@ - #include - #include "fuzzer.h" --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include "openvswitch/json.h" --#include "ovsdb-error.h" -+#include "openvswitch/ovsdb-error.h" - #include "ovsdb/table.h" - #include - #include -Index: openvswitch-2.17.2/tests/oss-fuzz/miniflow_target.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/oss-fuzz/miniflow_target.c -+++ openvswitch-2.17.2/tests/oss-fuzz/miniflow_target.c -@@ -1,13 +1,13 @@ - #include --#include "classifier.h" -+#include "internal/classifier.h" - #include "fuzzer.h" --#include "dp-packet.h" --#include "flow.h" -+#include "internal/dp-packet.h" -+#include "internal/flow.h" - #include "openvswitch/ofp-match.h" - #include "openvswitch/ofp-print.h" - #include "openvswitch/match.h" - #include "classifier-private.h" --#include "util.h" -+#include "internal/util.h" - - /* Returns a copy of 'src'. The caller must eventually free the returned - * miniflow with free(). */ -Index: openvswitch-2.17.2/tests/oss-fuzz/odp_target.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/oss-fuzz/odp_target.c -+++ openvswitch-2.17.2/tests/oss-fuzz/odp_target.c -@@ -4,10 +4,10 @@ - #include "odp-util.h" - #include - #include "openvswitch/dynamic-string.h" --#include "flow.h" -+#include "internal/flow.h" - #include "openvswitch/match.h" - #include "openvswitch/ofpbuf.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/ofp-flow.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/tests/oss-fuzz/ofctl_parse_target.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/oss-fuzz/ofctl_parse_target.c -+++ openvswitch-2.17.2/tests/oss-fuzz/ofctl_parse_target.c -@@ -6,7 +6,7 @@ - #include "openflow/openflow.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" --#include "util.h" -+#include "internal/util.h" - - static void - ofctl_parse_flows__(struct ofputil_flow_mod *fms, size_t n_fms, -Index: openvswitch-2.17.2/tests/oss-fuzz/ofp_print_target.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/oss-fuzz/ofp_print_target.c -+++ openvswitch-2.17.2/tests/oss-fuzz/ofp_print_target.c -@@ -1,6 +1,6 @@ - #include - #include "fuzzer.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/ofp-print.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" -Index: openvswitch-2.17.2/tests/ovstest.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/ovstest.c -+++ openvswitch-2.17.2/tests/ovstest.c -@@ -21,10 +21,10 @@ - #include - #include - #include --#include "command-line.h" -+#include "internal/command-line.h" - #include "openvswitch/dynamic-string.h" - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - static struct ovs_cmdl_command *commands = NULL; - static size_t n_commands = 0; -Index: openvswitch-2.17.2/tests/ovstest.h -=================================================================== ---- openvswitch-2.17.2.orig/tests/ovstest.h -+++ openvswitch-2.17.2/tests/ovstest.h -@@ -19,7 +19,7 @@ - - #include "openvswitch/compiler.h" - --#include "command-line.h" -+#include "internal/command-line.h" - - /* Overview - * ======== -Index: openvswitch-2.17.2/tests/test-aes128.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-aes128.c -+++ openvswitch-2.17.2/tests/test-aes128.c -@@ -19,7 +19,7 @@ - #include "aes128.h" - #include - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - static void - hex_to_uint8(const char *input, uint8_t *output, size_t n) -Index: openvswitch-2.17.2/tests/test-atomic.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-atomic.c -+++ openvswitch-2.17.2/tests/test-atomic.c -@@ -16,12 +16,12 @@ - - #include - #undef NDEBUG --#include "fatal-signal.h" --#include "ovs-atomic.h" -+#include "internal/fatal-signal.h" -+#include "openvswitch/ovs-atomic.h" - #include "ovstest.h" --#include "ovs-thread.h" --#include "timeval.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(test_atomic); -Index: openvswitch-2.17.2/tests/test-barrier.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-barrier.c -+++ openvswitch-2.17.2/tests/test-barrier.c -@@ -18,11 +18,11 @@ - - #include - --#include "ovs-thread.h" --#include "ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" -+#include "openvswitch/ovs-rcu.h" - #include "ovstest.h" --#include "random.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/util.h" - - #define DEFAULT_N_THREADS 4 - #define NB_STEPS 4 -Index: openvswitch-2.17.2/tests/test-bitmap.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-bitmap.c -+++ openvswitch-2.17.2/tests/test-bitmap.c -@@ -16,11 +16,11 @@ - - #include - #undef NDEBUG --#include "bitmap.h" -+#include "internal/bitmap.h" - #include --#include "command-line.h" -+#include "internal/command-line.h" - #include "ovstest.h" --#include "timeval.h" -+#include "internal/timeval.h" - - enum { MAX_BITS = 20 * BITMAP_ULONG_BITS }; - -Index: openvswitch-2.17.2/tests/test-bundle.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-bundle.c -+++ openvswitch-2.17.2/tests/test-bundle.c -@@ -17,12 +17,12 @@ - #undef NDEBUG - #include - #include --#include "bundle.h" --#include "flow.h" -+#include "internal/bundle.h" -+#include "internal/flow.h" - #include "openvswitch/ofp-actions.h" - #include "openvswitch/ofpbuf.h" - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - #define N_FLOWS 50000 - #define MAX_MEMBERS 8 /* Maximum supported by this test framework. */ -Index: openvswitch-2.17.2/tests/test-byte-order.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-byte-order.c -+++ openvswitch-2.17.2/tests/test-byte-order.c -@@ -16,7 +16,7 @@ - - #include - #undef NDEBUG --#include "byte-order.h" -+#include "internal/byte-order.h" - #include - #include - #include "ovstest.h" -Index: openvswitch-2.17.2/tests/test-ccmap.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-ccmap.c -+++ openvswitch-2.17.2/tests/test-ccmap.c -@@ -23,16 +23,16 @@ - #include - #include - #include --#include "bitmap.h" --#include "command-line.h" -+#include "internal/bitmap.h" -+#include "internal/command-line.h" - #include "fat-rwlock.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "ovstest.h" --#include "ovs-thread.h" --#include "random.h" --#include "timeval.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/random.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - typedef size_t hash_func(int value); - -Index: openvswitch-2.17.2/tests/test-classifier.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-classifier.c -+++ openvswitch-2.17.2/tests/test-classifier.c -@@ -28,23 +28,23 @@ - - #include - #undef NDEBUG --#include "classifier.h" -+#include "internal/classifier.h" - #include - #include - #include --#include "byte-order.h" -+#include "internal/byte-order.h" - #include "classifier-private.h" --#include "command-line.h" --#include "fatal-signal.h" --#include "flow.h" -+#include "internal/command-line.h" -+#include "internal/fatal-signal.h" -+#include "internal/flow.h" - #include "ovstest.h" --#include "ovs-atomic.h" --#include "ovs-thread.h" --#include "packets.h" --#include "random.h" --#include "timeval.h" --#include "unaligned.h" --#include "util.h" -+#include "openvswitch/ovs-atomic.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/packets.h" -+#include "internal/random.h" -+#include "internal/timeval.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - - static bool versioned = false; - -Index: openvswitch-2.17.2/tests/test-cmap.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-cmap.c -+++ openvswitch-2.17.2/tests/test-cmap.c -@@ -19,20 +19,20 @@ - - #include - #undef NDEBUG --#include "cmap.h" -+#include "internal/cmap.h" - #include - #include - #include --#include "bitmap.h" --#include "command-line.h" -+#include "internal/bitmap.h" -+#include "internal/command-line.h" - #include "fat-rwlock.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" - #include "ovstest.h" --#include "ovs-thread.h" --#include "random.h" --#include "timeval.h" --#include "util.h" -+#include "openvswitch/ovs-thread.h" -+#include "internal/random.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - /* Sample cmap element. */ - struct element { -Index: openvswitch-2.17.2/tests/test-conntrack.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-conntrack.c -+++ openvswitch-2.17.2/tests/test-conntrack.c -@@ -17,14 +17,14 @@ - #include - #include "conntrack.h" - --#include "dp-packet.h" --#include "fatal-signal.h" --#include "flow.h" --#include "netdev.h" --#include "ovs-thread.h" -+#include "internal/dp-packet.h" -+#include "internal/fatal-signal.h" -+#include "internal/flow.h" -+#include "internal/netdev.h" -+#include "openvswitch/ovs-thread.h" - #include "ovstest.h" - #include "pcap-file.h" --#include "timeval.h" -+#include "internal/timeval.h" - - static const char payload[] = "50540000000a50540000000908004500001c0000000000" - "11a4cd0a0101010a0101020001000200080000"; -Index: openvswitch-2.17.2/tests/test-csum.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-csum.c -+++ openvswitch-2.17.2/tests/test-csum.c -@@ -16,7 +16,7 @@ - - #include - #undef NDEBUG --#include "csum.h" -+#include "internal/csum.h" - #include - #include - #include -@@ -25,12 +25,12 @@ - #include - #include - #include --#include "crc32c.h" -+#include "internal/crc32c.h" - #include "ovstest.h" --#include "packets.h" --#include "random.h" --#include "unaligned.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/random.h" -+#include "internal/unaligned.h" -+#include "internal/util.h" - - struct test_case { - char *data; -Index: openvswitch-2.17.2/tests/test-flows.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-flows.c -+++ openvswitch-2.17.2/tests/test-flows.c -@@ -16,22 +16,22 @@ - - #include - #undef NDEBUG --#include "flow.h" -+#include "internal/flow.h" - #include - #include - #include - #include --#include "classifier.h" -+#include "internal/classifier.h" - #include "openflow/openflow.h" - #include "openvswitch/ofp-match.h" - #include "openvswitch/ofp-print.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/vlog.h" - #include "ovstest.h" --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "pcap-file.h" --#include "timeval.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - static void - test_flows_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) -Index: openvswitch-2.17.2/tests/test-hash.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-hash.c -+++ openvswitch-2.17.2/tests/test-hash.c -@@ -16,7 +16,7 @@ - - #include - #undef NDEBUG --#include "hash.h" -+#include "internal/hash.h" - #include - #include - #include -Index: openvswitch-2.17.2/tests/test-heap.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-heap.c -+++ openvswitch-2.17.2/tests/test-heap.c -@@ -23,10 +23,10 @@ - #include - #include - #include --#include "command-line.h" -+#include "internal/command-line.h" - #include "ovstest.h" --#include "random.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/util.h" - - /* Sample heap element. */ - struct element { -Index: openvswitch-2.17.2/tests/test-hindex.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-hindex.c -+++ openvswitch-2.17.2/tests/test-hindex.c -@@ -19,13 +19,13 @@ - - #include - #undef NDEBUG --#include "hindex.h" -+#include "internal/hindex.h" - #include - #include --#include "hash.h" -+#include "internal/hash.h" - #include "ovstest.h" --#include "random.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/util.h" - - /* Sample hindex element. */ - struct element { -Index: openvswitch-2.17.2/tests/test-hmap.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-hmap.c -+++ openvswitch-2.17.2/tests/test-hmap.c -@@ -22,10 +22,10 @@ - #include "openvswitch/hmap.h" - #include - #include --#include "hash.h" -+#include "internal/hash.h" - #include "ovstest.h" --#include "random.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/util.h" - - /* Sample hmap element. */ - struct element { -Index: openvswitch-2.17.2/tests/test-id-fpool.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-id-fpool.c -+++ openvswitch-2.17.2/tests/test-id-fpool.c -@@ -21,18 +21,18 @@ - - #include - --#include "command-line.h" -+#include "internal/command-line.h" - #include "id-fpool.h" --#include "id-pool.h" -+#include "internal/id-pool.h" - #include "openvswitch/vlog.h" - #include "openvswitch/util.h" --#include "ovs-thread.h" --#include "ovs-rcu.h" --#include "ovs-numa.h" -+#include "openvswitch/ovs-thread.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-numa.h" - #include "ovstest.h" --#include "random.h" --#include "timeval.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - static void - test_id_fpool_alloc(void) -Index: openvswitch-2.17.2/tests/test-json.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-json.c -+++ openvswitch-2.17.2/tests/test-json.c -@@ -22,9 +22,9 @@ - #include - #include - #include "ovstest.h" --#include "random.h" --#include "timeval.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - /* --pretty: If set, the JSON output is pretty-printed, instead of printed as - * compactly as possible. */ -Index: openvswitch-2.17.2/tests/test-jsonrpc.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-jsonrpc.c -+++ openvswitch-2.17.2/tests/test-jsonrpc.c -@@ -16,21 +16,21 @@ - - #include - #undef NDEBUG --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include - #include - #include - #include - #include --#include "command-line.h" --#include "daemon.h" -+#include "internal/command-line.h" -+#include "internal/daemon.h" - #include "openvswitch/json.h" - #include "ovstest.h" - #include "openvswitch/poll-loop.h" --#include "stream-ssl.h" --#include "stream.h" --#include "timeval.h" --#include "util.h" -+#include "internal/stream-ssl.h" -+#include "internal/stream.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - OVS_NO_RETURN static void usage(void); -Index: openvswitch-2.17.2/tests/test-lockfile.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-lockfile.c -+++ openvswitch-2.17.2/tests/test-lockfile.c -@@ -23,9 +23,9 @@ - #include - #include - #include "ovstest.h" --#include "process.h" --#include "timeval.h" --#include "util.h" -+#include "internal/process.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - struct test { -Index: openvswitch-2.17.2/tests/test-mpsc-queue.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-mpsc-queue.c -+++ openvswitch-2.17.2/tests/test-mpsc-queue.c -@@ -21,17 +21,17 @@ - - #include - --#include "command-line.h" -+#include "internal/command-line.h" - #include "guarded-list.h" - #include "mpsc-queue.h" - #include "openvswitch/list.h" - #include "openvswitch/util.h" - #include "openvswitch/vlog.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" - #include "ovstest.h" --#include "timeval.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - struct element { - union { -Index: openvswitch-2.17.2/tests/test-multipath.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-multipath.c -+++ openvswitch-2.17.2/tests/test-multipath.c -@@ -21,11 +21,11 @@ - #include - #include - #include --#include "flow.h" -+#include "internal/flow.h" - #include "multipath.h" - #include "openvswitch/ofp-actions.h" - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - static void - test_multipath_main(int argc, char *argv[]) -Index: openvswitch-2.17.2/tests/test-netflow.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-netflow.c -+++ openvswitch-2.17.2/tests/test-netflow.c -@@ -22,16 +22,16 @@ - #include - #include - #include --#include "command-line.h" --#include "daemon.h" -+#include "internal/command-line.h" -+#include "internal/daemon.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/ofpbuf.h" - #include "ovstest.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "socket-util.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - OVS_NO_RETURN static void usage(void); -Index: openvswitch-2.17.2/tests/test-netlink-policy.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-netlink-policy.c -+++ openvswitch-2.17.2/tests/test-netlink-policy.c -@@ -18,11 +18,11 @@ - - #include - --#include "netlink.h" -+#include "internal/netlink.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/types.h" - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - struct nlattr_fixture { - struct nlattr nlattr; -Index: openvswitch-2.17.2/tests/test-odp.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-odp.c -+++ openvswitch-2.17.2/tests/test-odp.c -@@ -19,11 +19,11 @@ - #include "odp-util.h" - #include - #include "openvswitch/dynamic-string.h" --#include "flow.h" -+#include "internal/flow.h" - #include "openvswitch/match.h" - #include "openvswitch/ofpbuf.h" - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - #include "openvswitch/ofp-flow.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/tests/test-ofpbuf.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-ofpbuf.c -+++ openvswitch-2.17.2/tests/test-ofpbuf.c -@@ -19,7 +19,7 @@ - #include - #include "openvswitch/ofpbuf.h" - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - #define BUF_SIZE 100 - #define HDR_OFS 10 -Index: openvswitch-2.17.2/tests/test-ovsdb.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-ovsdb.c -+++ openvswitch-2.17.2/tests/test-ovsdb.c -@@ -23,15 +23,15 @@ - #include - #include - --#include "byte-order.h" --#include "command-line.h" -+#include "internal/byte-order.h" -+#include "internal/command-line.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "jsonrpc.h" --#include "ovsdb-data.h" --#include "ovsdb-error.h" --#include "ovsdb-idl.h" --#include "ovsdb-types.h" -+#include "internal/jsonrpc.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-error.h" -+#include "openvswitch/ovsdb-idl.h" -+#include "openvswitch/ovsdb-types.h" - #include "ovsdb/column.h" - #include "ovsdb/condition.h" - #include "ovsdb/file.h" -@@ -46,11 +46,11 @@ - #include "ovsdb/transaction.h" - #include "ovsdb/trigger.h" - #include "openvswitch/poll-loop.h" --#include "stream.h" --#include "svec.h" -+#include "internal/stream.h" -+#include "internal/svec.h" - #include "tests/idltest.h" --#include "timeval.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(test_ovsdb); -Index: openvswitch-2.17.2/tests/test-packets.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-packets.c -+++ openvswitch-2.17.2/tests/test-packets.c -@@ -16,7 +16,7 @@ - - #include - #undef NDEBUG --#include "packets.h" -+#include "internal/packets.h" - #include - #include - #include -Index: openvswitch-2.17.2/tests/test-random.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-random.c -+++ openvswitch-2.17.2/tests/test-random.c -@@ -16,7 +16,7 @@ - - #include - #undef NDEBUG --#include "random.h" -+#include "internal/random.h" - #include - #include - #include "ovstest.h" -Index: openvswitch-2.17.2/tests/test-rcu.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-rcu.c -+++ openvswitch-2.17.2/tests/test-rcu.c -@@ -16,11 +16,11 @@ - - #include - #undef NDEBUG --#include "fatal-signal.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" -+#include "internal/fatal-signal.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - static void * - quiescer_main(void *aux OVS_UNUSED) -Index: openvswitch-2.17.2/tests/test-reconnect.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-reconnect.c -+++ openvswitch-2.17.2/tests/test-reconnect.c -@@ -21,11 +21,11 @@ - #include - #include - #include -+#include "internal/command-line.h" - #include "openvswitch/compiler.h" --#include "command-line.h" - #include "ovstest.h" --#include "svec.h" --#include "util.h" -+#include "internal/svec.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - static struct reconnect *reconnect; -Index: openvswitch-2.17.2/tests/test-rstp.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-rstp.c -+++ openvswitch-2.17.2/tests/test-rstp.c -@@ -9,8 +9,8 @@ - #include - #include "openvswitch/ofpbuf.h" - #include "ovstest.h" --#include "dp-packet.h" --#include "packets.h" -+#include "internal/dp-packet.h" -+#include "internal/packets.h" - #include "openvswitch/vlog.h" - - #define MAX_PORTS 10 -Index: openvswitch-2.17.2/tests/test-sflow.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-sflow.c -+++ openvswitch-2.17.2/tests/test-sflow.c -@@ -27,16 +27,16 @@ - #include - #include - #include --#include "command-line.h" --#include "daemon.h" -+#include "internal/command-line.h" -+#include "internal/daemon.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/ofpbuf.h" - #include "ovstest.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "socket-util.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - OVS_NO_RETURN static void usage(void); -Index: openvswitch-2.17.2/tests/test-sha1.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-sha1.c -+++ openvswitch-2.17.2/tests/test-sha1.c -@@ -23,8 +23,8 @@ - #include - #include - #include "ovstest.h" --#include "random.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/util.h" - - struct test_vector { - char *data; -Index: openvswitch-2.17.2/tests/test-skiplist.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-skiplist.c -+++ openvswitch-2.17.2/tests/test-skiplist.c -@@ -22,9 +22,9 @@ - #include - #include - #include "ovstest.h" --#include "skiplist.h" --#include "random.h" --#include "util.h" -+#include "internal/skiplist.h" -+#include "internal/random.h" -+#include "internal/util.h" - - static void - test_skiplist_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED); -Index: openvswitch-2.17.2/tests/test-stopwatch.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-stopwatch.c -+++ openvswitch-2.17.2/tests/test-stopwatch.c -@@ -16,12 +16,12 @@ - - #include - #undef NDEBUG --#include "stopwatch.h" -+#include "internal/stopwatch.h" - #include - #include - #include - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - #define MAX_SAMPLES 100 - #define UNIT SW_MS -Index: openvswitch-2.17.2/tests/test-stp.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-stp.c -+++ openvswitch-2.17.2/tests/test-stp.c -@@ -23,10 +23,10 @@ - #include - #include - #include --#include "dp-packet.h" -+#include "internal/dp-packet.h" - #include "openvswitch/ofpbuf.h" - #include "ovstest.h" --#include "packets.h" -+#include "internal/packets.h" - #include "openvswitch/vlog.h" - - struct bpdu { -Index: openvswitch-2.17.2/tests/test-stream.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-stream.c -+++ openvswitch-2.17.2/tests/test-stream.c -@@ -16,10 +16,10 @@ - - #include - --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/vlog.h" --#include "stream.h" --#include "util.h" -+#include "internal/stream.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(test_stream); - -Index: openvswitch-2.17.2/tests/test-unix-socket.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-unix-socket.c -+++ openvswitch-2.17.2/tests/test-unix-socket.c -@@ -16,12 +16,12 @@ - - #include - #undef NDEBUG --#include "socket-util.h" -+#include "internal/socket-util.h" - #include - #include - #include - #include "ovstest.h" --#include "util.h" -+#include "internal/util.h" - - static void - test_unix_socket_main(int argc, char *argv[]) -Index: openvswitch-2.17.2/tests/test-unixctl.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-unixctl.c -+++ openvswitch-2.17.2/tests/test-unixctl.c -@@ -17,14 +17,14 @@ - - #include - --#include "command-line.h" --#include "daemon.h" --#include "fatal-signal.h" -+#include "internal/command-line.h" -+#include "internal/daemon.h" -+#include "internal/fatal-signal.h" - #include "openvswitch/vlog.h" - #include "ovstest.h" - #include "openvswitch/poll-loop.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(test_unixctl); - -Index: openvswitch-2.17.2/tests/test-util.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-util.c -+++ openvswitch-2.17.2/tests/test-util.c -@@ -16,17 +16,17 @@ - - #include - #undef NDEBUG --#include "util.h" -+#include "internal/util.h" - #include - #include - #include - #include - #include - #include --#include "byte-order.h" --#include "command-line.h" -+#include "internal/byte-order.h" -+#include "internal/command-line.h" - #include "ovstest.h" --#include "random.h" -+#include "internal/random.h" - #include "sat-math.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/tests/test-uuid.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-uuid.c -+++ openvswitch-2.17.2/tests/test-uuid.c -@@ -16,8 +16,8 @@ - - #include - #undef NDEBUG --#include "util.h" --#include "uuid.h" -+#include "internal/util.h" -+#include "internal/uuid.h" - #include - #include "ovstest.h" - -Index: openvswitch-2.17.2/tests/test-vconn.c -=================================================================== ---- openvswitch-2.17.2.orig/tests/test-vconn.c -+++ openvswitch-2.17.2/tests/test-vconn.c -@@ -22,8 +22,8 @@ - #include - #include - #include --#include "command-line.h" --#include "fatal-signal.h" -+#include "internal/command-line.h" -+#include "internal/fatal-signal.h" - #include "openflow/openflow.h" - #include "openvswitch/ofp-msgs.h" - #include "openvswitch/ofpbuf.h" -@@ -31,11 +31,11 @@ - #include "openvswitch/vlog.h" - #include "ovstest.h" - #include "openvswitch/poll-loop.h" --#include "socket-util.h" --#include "stream.h" --#include "stream-ssl.h" --#include "timeval.h" --#include "util.h" -+#include "internal/socket-util.h" -+#include "internal/stream.h" -+#include "internal/stream-ssl.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - #define TIMEOUT 10 - -Index: openvswitch-2.17.2/utilities/nlmon.c -=================================================================== ---- openvswitch-2.17.2.orig/utilities/nlmon.c -+++ openvswitch-2.17.2/utilities/nlmon.c -@@ -23,13 +23,13 @@ - #include - #include - #include --#include "netlink.h" -+#include "internal/netlink.h" - #include "netlink-socket.h" - #include "netnsid.h" - #include "openvswitch/ofpbuf.h" - #include "openvswitch/poll-loop.h" --#include "timeval.h" --#include "util.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - static const struct nl_policy rtnlgrp_link_policy[] = { -Index: openvswitch-2.17.2/utilities/ovs-appctl.c -=================================================================== ---- openvswitch-2.17.2.orig/utilities/ovs-appctl.c -+++ openvswitch-2.17.2/utilities/ovs-appctl.c -@@ -22,15 +22,15 @@ - #include - #include - --#include "command-line.h" --#include "daemon.h" --#include "dirs.h" -+#include "internal/command-line.h" -+#include "internal/daemon.h" -+#include "internal/dirs.h" - #include "openvswitch/dynamic-string.h" --#include "jsonrpc.h" --#include "process.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/jsonrpc.h" -+#include "internal/process.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - static void usage(void); -Index: openvswitch-2.17.2/utilities/ovs-dpctl.c -=================================================================== ---- openvswitch-2.17.2.orig/utilities/ovs-dpctl.c -+++ openvswitch-2.17.2/utilities/ovs-dpctl.c -@@ -32,14 +32,14 @@ - #include - - #include "openvswitch/compiler.h" --#include "command-line.h" --#include "dirs.h" -+#include "internal/command-line.h" -+#include "internal/dirs.h" - #include "dpctl.h" --#include "fatal-signal.h" -+#include "internal/fatal-signal.h" - #include "odp-util.h" --#include "packets.h" --#include "timeval.h" --#include "util.h" -+#include "internal/packets.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - static struct dpctl_params dpctl_p; -Index: openvswitch-2.17.2/utilities/ovs-ofctl.c -=================================================================== ---- openvswitch-2.17.2.orig/utilities/ovs-ofctl.c -+++ openvswitch-2.17.2/utilities/ovs-ofctl.c -@@ -29,16 +29,16 @@ - #include - #include - --#include "byte-order.h" --#include "classifier.h" --#include "command-line.h" --#include "daemon.h" --#include "colors.h" -+#include "internal/byte-order.h" -+#include "internal/classifier.h" -+#include "internal/daemon.h" -+#include "internal/command-line.h" -+#include "internal/colors.h" - #include "openvswitch/compiler.h" --#include "dirs.h" --#include "dp-packet.h" --#include "fatal-signal.h" --#include "nx-match.h" -+#include "internal/dirs.h" -+#include "internal/dp-packet.h" -+#include "internal/fatal-signal.h" -+#include "internal/nx-match.h" - #include "odp-util.h" - #include "ofp-version-opt.h" - #include "ofproto/ofproto.h" -@@ -65,16 +65,16 @@ - #include "openvswitch/shash.h" - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" --#include "packets.h" -+#include "internal/packets.h" - #include "pcap-file.h" - #include "openvswitch/poll-loop.h" --#include "random.h" --#include "sort.h" --#include "stream-ssl.h" --#include "socket-util.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/random.h" -+#include "internal/sort.h" -+#include "internal/stream-ssl.h" -+#include "internal/socket-util.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(ofctl); - -Index: openvswitch-2.17.2/utilities/ovs-testcontroller.c -=================================================================== ---- openvswitch-2.17.2.orig/utilities/ovs-testcontroller.c -+++ openvswitch-2.17.2/utilities/ovs-testcontroller.c -@@ -24,25 +24,25 @@ - #include - #include - -+#include "internal/command-line.h" - #include "openvswitch/compiler.h" --#include "command-line.h" --#include "daemon.h" --#include "fatal-signal.h" -+#include "internal/daemon.h" -+#include "internal/fatal-signal.h" - #include "learning-switch.h" - #include "ofp-version-opt.h" - #include "openvswitch/ofpbuf.h" - #include "openflow/openflow.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/rconn.h" --#include "simap.h" --#include "stream-ssl.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/simap.h" -+#include "internal/stream-ssl.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" -+#include "internal/util.h" - #include "openvswitch/ofp-flow.h" - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" --#include "socket-util.h" -+#include "internal/socket-util.h" - - - VLOG_DEFINE_THIS_MODULE(controller); -Index: openvswitch-2.17.2/utilities/ovs-vsctl.c -=================================================================== ---- openvswitch-2.17.2.orig/utilities/ovs-vsctl.c -+++ openvswitch-2.17.2/utilities/ovs-vsctl.c -@@ -27,32 +27,32 @@ - #include - #include - --#include "db-ctl-base.h" -+#include "internal/db-ctl-base.h" - - #include "openvswitch/compiler.h" --#include "command-line.h" --#include "dirs.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/command-line.h" -+#include "internal/dirs.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" - #include "openvswitch/ofp-parse.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" --#include "ovsdb-data.h" --#include "ovsdb-idl.h" --#include "process.h" --#include "simap.h" --#include "stream.h" --#include "stream-ssl.h" --#include "smap.h" --#include "sset.h" --#include "svec.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-idl.h" -+#include "internal/process.h" -+#include "internal/simap.h" -+#include "internal/stream.h" -+#include "internal/stream-ssl.h" -+#include "internal/smap.h" -+#include "internal/sset.h" -+#include "internal/svec.h" - #include "lib/vswitch-idl.h" --#include "table.h" --#include "timeval.h" --#include "util.h" -+#include "internal/table.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(vsctl); - -Index: openvswitch-2.17.2/vswitchd/bridge.c -=================================================================== ---- openvswitch-2.17.2.orig/vswitchd/bridge.c -+++ openvswitch-2.17.2/vswitchd/bridge.c -@@ -21,25 +21,25 @@ - - #include "async-append.h" - #include "bfd.h" --#include "bitmap.h" -+#include "internal/bitmap.h" - #include "cfm.h" - #include "connectivity.h" --#include "coverage.h" --#include "daemon.h" --#include "dirs.h" -+#include "internal/coverage.h" -+#include "internal/daemon.h" -+#include "internal/dirs.h" - #include "dpif.h" - #include "dpdk.h" --#include "hash.h" -+#include "internal/hash.h" - #include "openvswitch/hmap.h" --#include "hmapx.h" -+#include "internal/hmapx.h" - #include "if-notifier.h" --#include "jsonrpc.h" -+#include "internal/jsonrpc.h" - #include "lacp.h" - #include "mac-learning.h" --#include "mcast-snooping.h" --#include "netdev.h" -+#include "internal/mcast-snooping.h" -+#include "internal/netdev.h" - #include "netdev-offload.h" --#include "nx-match.h" -+#include "internal/nx-match.h" - #include "ofproto/bond.h" - #include "ofproto/ofproto.h" - #include "openvswitch/dynamic-string.h" -@@ -50,24 +50,24 @@ - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" - #include "ovs-lldp.h" --#include "ovs-numa.h" --#include "packets.h" -+#include "openvswitch/ovs-numa.h" -+#include "internal/packets.h" - #include "openvswitch/poll-loop.h" --#include "seq.h" -+#include "internal/seq.h" - #include "sflow_api.h" - #include "sha1.h" - #include "openvswitch/shash.h" --#include "smap.h" --#include "socket-util.h" --#include "stream.h" --#include "stream-ssl.h" --#include "sset.h" -+#include "internal/smap.h" -+#include "internal/socket-util.h" -+#include "internal/stream.h" -+#include "internal/stream-ssl.h" -+#include "internal/sset.h" - #include "system-stats.h" --#include "timeval.h" -+#include "internal/timeval.h" - #include "tnl-ports.h" - #include "userspace-tso.h" --#include "util.h" --#include "unixctl.h" -+#include "internal/util.h" -+#include "internal/unixctl.h" - #include "lib/vswitch-idl.h" - #include "xenserver.h" - #include "vlan-bitmap.h" -Index: openvswitch-2.17.2/vswitchd/ovs-vswitchd.c -=================================================================== ---- openvswitch-2.17.2.orig/vswitchd/ovs-vswitchd.c -+++ openvswitch-2.17.2/vswitchd/ovs-vswitchd.c -@@ -27,32 +27,32 @@ - - #include "bridge.h" - #include "openvswitch/compiler.h" --#include "command-line.h" --#include "daemon.h" --#include "dirs.h" -+#include "internal/command-line.h" -+#include "internal/daemon.h" -+#include "internal/dirs.h" - #include "dpif.h" - #include "dummy.h" --#include "fatal-signal.h" --#include "memory.h" --#include "netdev.h" -+#include "internal/fatal-signal.h" -+#include "internal/memory.h" -+#include "internal/netdev.h" - #include "openflow/openflow.h" --#include "ovsdb-idl.h" --#include "ovs-rcu.h" -+#include "openvswitch/ovsdb-idl.h" -+#include "openvswitch/ovs-rcu.h" - #include "ovs-router.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" --#include "simap.h" --#include "stream-ssl.h" --#include "stream.h" --#include "svec.h" --#include "timeval.h" --#include "unixctl.h" --#include "util.h" -+#include "internal/simap.h" -+#include "internal/stream-ssl.h" -+#include "internal/stream.h" -+#include "internal/svec.h" -+#include "internal/timeval.h" -+#include "internal/unixctl.h" - #include "openvswitch/usdt-probes.h" - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" - #include "lib/vswitch-idl.h" - #include "lib/dns-resolve.h" -+#include "internal/util.h" - - VLOG_DEFINE_THIS_MODULE(vswitchd); - -Index: openvswitch-2.17.2/vswitchd/system-stats.c -=================================================================== ---- openvswitch-2.17.2.orig/vswitchd/system-stats.c -+++ openvswitch-2.17.2/vswitchd/system-stats.c -@@ -31,19 +31,19 @@ - #endif - #include - --#include "daemon.h" --#include "dirs.h" -+#include "internal/daemon.h" -+#include "internal/dirs.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/json.h" --#include "latch.h" -+#include "internal/latch.h" - #include "openvswitch/ofpbuf.h" --#include "ovs-rcu.h" --#include "ovs-thread.h" -+#include "openvswitch/ovs-rcu.h" -+#include "openvswitch/ovs-thread.h" - #include "openvswitch/poll-loop.h" - #include "openvswitch/shash.h" --#include "process.h" --#include "smap.h" --#include "timeval.h" -+#include "internal/process.h" -+#include "internal/smap.h" -+#include "internal/timeval.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(system_stats); -Index: openvswitch-2.17.2/vswitchd/xenserver.c -=================================================================== ---- openvswitch-2.17.2.orig/vswitchd/xenserver.c -+++ openvswitch-2.17.2/vswitchd/xenserver.c -@@ -22,8 +22,8 @@ - #include - #include - #include "openvswitch/dynamic-string.h" --#include "process.h" --#include "util.h" -+#include "internal/process.h" -+#include "internal/util.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(xenserver); -Index: openvswitch-2.17.2/vtep/vtep-ctl.c -=================================================================== ---- openvswitch-2.17.2.orig/vtep/vtep-ctl.c -+++ openvswitch-2.17.2/vtep/vtep-ctl.c -@@ -27,27 +27,27 @@ - #include - #include - --#include "db-ctl-base.h" -+#include "internal/db-ctl-base.h" - - #include "openvswitch/compiler.h" - #include "openvswitch/dynamic-string.h" --#include "command-line.h" --#include "fatal-signal.h" --#include "hash.h" -+#include "internal/command-line.h" -+#include "internal/fatal-signal.h" -+#include "internal/hash.h" - #include "openvswitch/json.h" --#include "ovsdb-data.h" --#include "ovsdb-idl.h" -+#include "openvswitch/ovsdb-data.h" -+#include "openvswitch/ovsdb-idl.h" - #include "openvswitch/poll-loop.h" --#include "process.h" --#include "stream.h" --#include "stream-ssl.h" --#include "smap.h" --#include "sset.h" --#include "svec.h" -+#include "internal/process.h" -+#include "internal/stream.h" -+#include "internal/stream-ssl.h" -+#include "internal/smap.h" -+#include "internal/sset.h" -+#include "internal/svec.h" - #include "vtep/vtep-idl.h" --#include "table.h" --#include "timeval.h" --#include "util.h" -+#include "internal/table.h" -+#include "internal/timeval.h" -+#include "internal/util.h" - #include "openvswitch/vconn.h" - #include "openvswitch/vlog.h" - -Index: openvswitch-2.17.2/include/internal/bundle.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/bundle.h -@@ -0,0 +1,59 @@ -+/* Copyright (c) 2011, 2012, 2013, 2014, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef BUNDLE_H -+#define BUNDLE_H 1 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "openvswitch/compiler.h" -+#include "openflow/nicira-ext.h" -+#include "openvswitch/ofp-errors.h" -+#include "openvswitch/types.h" -+ -+struct ds; -+struct flow; -+struct flow_wildcards; -+struct match; -+struct ofpact_bundle; -+struct ofpbuf; -+struct ofputil_port_map; -+ -+/* NXAST_BUNDLE helper functions. -+ * -+ * See lib/ofp-actions.c for NXAST_BUNDLE specification. */ -+ -+#define BUNDLE_MAX_MEMBERS 2048 -+ -+ofp_port_t bundle_execute(const struct ofpact_bundle *, const struct flow *, -+ struct flow_wildcards *wc, -+ bool (*member_enabled)(ofp_port_t ofp_port, void *aux), -+ void *aux); -+enum ofperr bundle_check(const struct ofpact_bundle *, ofp_port_t max_ports, -+ const struct match *); -+char *bundle_parse(const char *, const struct ofputil_port_map *port_map, -+ struct ofpbuf *ofpacts) OVS_WARN_UNUSED_RESULT; -+char *bundle_parse_load(const char *, const struct ofputil_port_map *port_map, -+ struct ofpbuf *ofpacts) -+ OVS_WARN_UNUSED_RESULT; -+void bundle_format(const struct ofpact_bundle *, -+ const struct ofputil_port_map *, struct ds *); -+ -+#endif /* bundle.h */ -Index: openvswitch-2.17.2/include/internal/byte-order.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/byte-order.h -@@ -0,0 +1,148 @@ -+/* -+ * Copyright (c) 2008, 2010, 2011, 2013, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+#ifndef BYTE_ORDER_H -+#define BYTE_ORDER_H 1 -+ -+#include -+#include -+#include -+#include -+#include "openvswitch/types.h" -+ -+#ifndef __CHECKER__ -+#if !(defined(_WIN32) || defined(htonll)) -+static inline ovs_be64 -+htonll(uint64_t n) -+{ -+ return htonl(1) == 1 ? n : ((uint64_t) htonl(n) << 32) | htonl(n >> 32); -+} -+ -+static inline uint64_t -+ntohll(ovs_be64 n) -+{ -+ return htonl(1) == 1 ? n : ((uint64_t) ntohl(n) << 32) | ntohl(n >> 32); -+} -+#endif /* !(defined(_WIN32) || defined(htonll)) */ -+#else -+/* Making sparse happy with these functions also makes them unreadable, so -+ * don't bother to show it their implementations. */ -+ovs_be64 htonll(uint64_t); -+uint64_t ntohll(ovs_be64); -+#endif -+ -+static inline ovs_be128 -+hton128(const ovs_u128 src) -+{ -+ ovs_be128 dst; -+ -+ dst.be64.hi = htonll(src.u64.hi); -+ dst.be64.lo = htonll(src.u64.lo); -+ return dst; -+} -+ -+static inline ovs_u128 -+ntoh128(const ovs_be128 src) -+{ -+ ovs_u128 dst; -+ -+ dst.u64.hi = ntohll(src.be64.hi); -+ dst.u64.lo = ntohll(src.be64.lo); -+ return dst; -+} -+ -+static inline uint32_t -+uint32_byteswap(uint32_t crc) { -+ return (((crc & 0x000000ff) << 24) | -+ ((crc & 0x0000ff00) << 8) | -+ ((crc & 0x00ff0000) >> 8) | -+ ((crc & 0xff000000) >> 24)); -+} -+ -+/* These macros may substitute for htons(), htonl(), and htonll() in contexts -+ * where function calls are not allowed, such as case labels. They should not -+ * be used elsewhere because all of them evaluate their argument many times. */ -+#if defined(WORDS_BIGENDIAN) || __CHECKER__ -+#define CONSTANT_HTONS(VALUE) ((OVS_FORCE ovs_be16) ((VALUE) & 0xffff)) -+#define CONSTANT_HTONL(VALUE) ((OVS_FORCE ovs_be32) ((VALUE) & 0xffffffff)) -+#define CONSTANT_HTONLL(VALUE) \ -+ ((OVS_FORCE ovs_be64) ((VALUE) & UINT64_C(0xffffffffffffffff))) -+#else -+#define CONSTANT_HTONS(VALUE) \ -+ (((((ovs_be16) (VALUE)) & 0xff00) >> 8) | \ -+ ((((ovs_be16) (VALUE)) & 0x00ff) << 8)) -+#define CONSTANT_HTONL(VALUE) \ -+ (((((ovs_be32) (VALUE)) & 0x000000ff) << 24) | \ -+ ((((ovs_be32) (VALUE)) & 0x0000ff00) << 8) | \ -+ ((((ovs_be32) (VALUE)) & 0x00ff0000) >> 8) | \ -+ ((((ovs_be32) (VALUE)) & 0xff000000) >> 24)) -+#define CONSTANT_HTONLL(VALUE) \ -+ (((((ovs_be64) (VALUE)) & UINT64_C(0x00000000000000ff)) << 56) | \ -+ ((((ovs_be64) (VALUE)) & UINT64_C(0x000000000000ff00)) << 40) | \ -+ ((((ovs_be64) (VALUE)) & UINT64_C(0x0000000000ff0000)) << 24) | \ -+ ((((ovs_be64) (VALUE)) & UINT64_C(0x00000000ff000000)) << 8) | \ -+ ((((ovs_be64) (VALUE)) & UINT64_C(0x000000ff00000000)) >> 8) | \ -+ ((((ovs_be64) (VALUE)) & UINT64_C(0x0000ff0000000000)) >> 24) | \ -+ ((((ovs_be64) (VALUE)) & UINT64_C(0x00ff000000000000)) >> 40) | \ -+ ((((ovs_be64) (VALUE)) & UINT64_C(0xff00000000000000)) >> 56)) -+#endif -+ -+/* Returns the ovs_be32 that you would get from: -+ * -+ * union { uint8_t b[4]; ovs_be32 be32; } x = { .b = { b0, b1, b2, b3 } }; -+ * return x.be32; -+ * -+ * but without the undefined behavior. */ -+static inline ovs_be32 -+bytes_to_be32(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) -+{ -+#if WORDS_BIGENDIAN -+ uint32_t x = ((uint32_t) b0 << 24) | (b1 << 16) | (b2 << 8) | b3; -+#else -+ uint32_t x = ((uint32_t) b3 << 24) | (b2 << 16) | (b1 << 8) | b0; -+#endif -+ return (OVS_FORCE ovs_be32) x; -+} -+ -+/* These functions zero-extend big-endian values to longer ones, -+ * or truncate long big-endian value to shorter ones. */ -+#ifndef __CHECKER__ -+#if WORDS_BIGENDIAN -+static inline ovs_be32 be16_to_be32(ovs_be16 x) { return x; } -+static inline ovs_be64 be16_to_be64(ovs_be16 x) { return x; } -+static inline ovs_be64 be32_to_be64(ovs_be32 x) { return x; } -+static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x; } -+static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x; } -+static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x; } -+#else /* !WORDS_BIGENDIAN */ -+static inline ovs_be32 be16_to_be32(ovs_be16 x) { return (ovs_be32) x << 16; } -+static inline ovs_be64 be16_to_be64(ovs_be16 x) { return (ovs_be64) x << 48; } -+static inline ovs_be64 be32_to_be64(ovs_be32 x) { return (ovs_be64) x << 32; } -+static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x >> 32; } -+static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x >> 48; } -+static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x >> 16; } -+#endif /* !WORDS_BIGENDIAN */ -+#else /* __CHECKER__ */ -+/* Making sparse happy with these functions also makes them unreadable, so -+ * don't bother to show it their implementations. */ -+ovs_be32 be16_to_be32(ovs_be16); -+ovs_be64 be16_to_be64(ovs_be16); -+ovs_be64 be32_to_be64(ovs_be32); -+ovs_be32 be64_to_be32(ovs_be64); -+ovs_be16 be64_to_be16(ovs_be64); -+ovs_be16 be32_to_be16(ovs_be32); -+#endif -+ -+#endif /* byte-order.h */ -Index: openvswitch-2.17.2/include/internal/colors.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/colors.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (c) 2016 6WIND S.A. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef COLORS_H -+#define COLORS_H 1 -+ -+#include -+ -+struct colors { -+ /* Color codes for various situation. Each of these is a fully formed -+ * Select Graphic Rendition (SGR, "\33[...m") start string for the -+ * appropriate color. -+ */ -+ char *actions; -+ char *drop; -+ char *learn; -+ char *param; -+ char *paren; -+ char *special; -+ char *value; -+ -+ /* SGR end string. */ -+ char *end; -+}; -+extern struct colors colors; -+ -+void colors_init(bool enable_color); -+ -+#endif /* colors.h */ -Index: openvswitch-2.17.2/include/internal/command-line.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/command-line.h -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef COMMAND_LINE_H -+#define COMMAND_LINE_H 1 -+ -+/* Utilities for command-line parsing. */ -+ -+#include "openvswitch/compiler.h" -+ -+struct option; -+ -+/* Command handler context */ -+struct ovs_cmdl_context { -+ /* number of command line arguments */ -+ int argc; -+ /* array of command line arguments */ -+ char **argv; -+ /* private context data defined by the API user */ -+ void *pvt; -+}; -+ -+typedef void (*ovs_cmdl_handler)(struct ovs_cmdl_context *); -+ -+struct ovs_cmdl_command { -+ const char *name; -+ const char *usage; -+ int min_args; -+ int max_args; -+ ovs_cmdl_handler handler; -+ enum { OVS_RO, OVS_RW } mode; /* Does this command modify things? */ -+}; -+ -+char *ovs_cmdl_long_options_to_short_options(const struct option *options); -+ -+struct ovs_cmdl_parsed_option { -+ const struct option *o; -+ char *arg; -+}; -+char *ovs_cmdl_parse_all(int argc, char *argv[], const struct option *, -+ struct ovs_cmdl_parsed_option **, size_t *) -+ OVS_WARN_UNUSED_RESULT; -+ -+char **ovs_cmdl_env_parse_all(int *argcp, char *argv_[], -+ const char *env_options); -+ -+void ovs_cmdl_print_options(const struct option *options); -+void ovs_cmdl_print_commands(const struct ovs_cmdl_command *commands); -+ -+void ovs_cmdl_run_command(struct ovs_cmdl_context *, -+ const struct ovs_cmdl_command[]); -+void ovs_cmdl_run_command_read_only(struct ovs_cmdl_context *, -+ const struct ovs_cmdl_command[]); -+ -+void ovs_cmdl_proctitle_init(int argc, char **argv); -+#if defined(__FreeBSD__) || defined(__NetBSD__) -+#define ovs_cmdl_proctitle_set setproctitle -+#else -+void ovs_cmdl_proctitle_set(const char *, ...) -+ OVS_PRINTF_FORMAT(1, 2); -+#endif -+void ovs_cmdl_proctitle_restore(void); -+ -+#endif /* command-line.h */ -Index: openvswitch-2.17.2/include/internal/crc32c.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/crc32c.h -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (c) 2012 The University of Waikato. -+ * Author: Joe Stringer -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef CRC32C_H -+#define CRC32C_H 1 -+ -+#include "openvswitch/types.h" -+ -+ovs_be32 crc32c(const uint8_t *data, size_t); -+ -+#endif /* crc32c.h */ -Index: openvswitch-2.17.2/include/internal/csum.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/csum.h -@@ -0,0 +1,59 @@ -+/* -+ * Copyright (c) 2008, 2011, 2015 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef CSUM_H -+#define CSUM_H 1 -+ -+#include -+#include -+#include "openvswitch/types.h" -+ -+struct in6_addr; -+ -+ovs_be16 csum(const void *, size_t); -+uint32_t csum_continue(uint32_t partial, const void *, size_t); -+ovs_be16 csum_finish(uint32_t partial); -+ovs_be16 recalc_csum16(ovs_be16 old_csum, ovs_be16 old_u16, ovs_be16 new_u16); -+ovs_be16 recalc_csum32(ovs_be16 old_csum, ovs_be32 old_u32, ovs_be32 new_u32); -+ovs_be16 recalc_csum48(ovs_be16 old_csum, const struct eth_addr old_mac, -+ const struct eth_addr new_mac); -+ovs_be16 recalc_csum128(ovs_be16 old_csum, ovs_16aligned_be32 old_u32[4], -+ const struct in6_addr *); -+ -+#ifndef __CHECKER__ -+/* Adds the 16 bits in 'new' to the partial IP checksum 'partial' and returns -+ * the updated checksum. (To start a new checksum, pass 0 for 'partial'. To -+ * obtain the finished checksum, pass the return value to csum_finish().) */ -+static inline uint32_t -+csum_add16(uint32_t partial, ovs_be16 new) -+{ -+ return partial + new; -+} -+ -+/* Adds the 32 bits in 'new' to the partial IP checksum 'partial' and returns -+ * the updated checksum. (To start a new checksum, pass 0 for 'partial'. To -+ * obtain the finished checksum, pass the return value to csum_finish().) */ -+static inline uint32_t -+csum_add32(uint32_t partial, ovs_be32 new) -+{ -+ return partial + (new >> 16) + (new & 0xffff); -+} -+#else -+uint32_t csum_add16(uint32_t partial, ovs_be16); -+uint32_t csum_add32(uint32_t partial, ovs_be32); -+#endif -+ -+#endif /* csum.h */ -Index: openvswitch-2.17.2/include/internal/daemon.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/daemon.h -@@ -0,0 +1,183 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef DAEMON_H -+#define DAEMON_H 1 -+ -+#include -+#include -+#include -+ -+/* This file provides an interface for utilities to run in the background -+ * as daemons on POSIX platforms like Linux or as services on Windows platform. -+ * Some of the functionalities defined in this file are only applicable to -+ * POSIX platforms and some are applicable only on Windows. As such, the -+ * function definitions unique to each platform are separated out with -+ * ifdef macros. More descriptive comments on individual functions are provided -+ * in daemon-unix.c (for POSIX platforms) and daemon-windows.c (for Windows). -+ -+ * The DAEMON_OPTION_ENUMS, DAEMON_LONG_OPTIONS and DAEMON_OPTION_HANDLERS -+ * macros are useful for parsing command-line options in individual utilities. -+ * For e.g., the command-line option "--monitor" is recognized on Linux -+ * and results in calling the daemon_set_monitor() function. The same option is -+ * not recognized on Windows platform. -+ */ -+ -+#ifndef _WIN32 -+#define DAEMON_OPTION_ENUMS \ -+ OPT_DETACH, \ -+ OPT_NO_SELF_CONFINEMENT, \ -+ OPT_NO_CHDIR, \ -+ OPT_OVERWRITE_PIDFILE, \ -+ OPT_PIDFILE, \ -+ OPT_MONITOR, \ -+ OPT_USER_GROUP -+ -+#define DAEMON_LONG_OPTIONS \ -+ {"detach", no_argument, NULL, OPT_DETACH}, \ -+ {"no-self-confinement", no_argument, NULL, OPT_NO_SELF_CONFINEMENT}, \ -+ {"no-chdir", no_argument, NULL, OPT_NO_CHDIR}, \ -+ {"pidfile", optional_argument, NULL, OPT_PIDFILE}, \ -+ {"overwrite-pidfile", no_argument, NULL, OPT_OVERWRITE_PIDFILE}, \ -+ {"monitor", no_argument, NULL, OPT_MONITOR}, \ -+ {"user", required_argument, NULL, OPT_USER_GROUP} -+ -+#define DAEMON_OPTION_HANDLERS \ -+ case OPT_DETACH: \ -+ set_detach(); \ -+ break; \ -+ \ -+ case OPT_NO_SELF_CONFINEMENT: \ -+ daemon_disable_self_confinement(); \ -+ break; \ -+ \ -+ case OPT_NO_CHDIR: \ -+ set_no_chdir(); \ -+ break; \ -+ \ -+ case OPT_PIDFILE: \ -+ set_pidfile(optarg); \ -+ break; \ -+ \ -+ case OPT_OVERWRITE_PIDFILE: \ -+ ignore_existing_pidfile(); \ -+ break; \ -+ \ -+ case OPT_MONITOR: \ -+ daemon_set_monitor(); \ -+ break; \ -+ \ -+ case OPT_USER_GROUP: \ -+ daemon_set_new_user(optarg); \ -+ break; -+ -+#define DAEMON_OPTION_CASES \ -+ case OPT_DETACH: \ -+ case OPT_NO_SELF_CONFINEMENT: \ -+ case OPT_NO_CHDIR: \ -+ case OPT_PIDFILE: \ -+ case OPT_OVERWRITE_PIDFILE: \ -+ case OPT_MONITOR: \ -+ case OPT_USER_GROUP: -+ -+void set_detach(void); -+void daemon_set_monitor(void); -+void set_no_chdir(void); -+void ignore_existing_pidfile(void); -+pid_t read_pidfile(const char *name); -+#else -+#define DAEMON_OPTION_ENUMS \ -+ OPT_DETACH, \ -+ OPT_NO_SELF_CONFINEMENT, \ -+ OPT_NO_CHDIR, \ -+ OPT_PIDFILE, \ -+ OPT_PIPE_HANDLE, \ -+ OPT_SERVICE, \ -+ OPT_SERVICE_MONITOR, \ -+ OPT_USER_GROUP -+ -+#define DAEMON_LONG_OPTIONS \ -+ {"detach", no_argument, NULL, OPT_DETACH}, \ -+ {"no-self-confinement", no_argument, NULL, OPT_NO_SELF_CONFINEMENT}, \ -+ {"no-chdir", no_argument, NULL, OPT_NO_CHDIR}, \ -+ {"pidfile", optional_argument, NULL, OPT_PIDFILE}, \ -+ {"pipe-handle", required_argument, NULL, OPT_PIPE_HANDLE}, \ -+ {"service", no_argument, NULL, OPT_SERVICE}, \ -+ {"service-monitor", no_argument, NULL, OPT_SERVICE_MONITOR}, \ -+ {"user", required_argument, NULL, OPT_USER_GROUP} -+ -+#define DAEMON_OPTION_HANDLERS \ -+ case OPT_DETACH: \ -+ set_detach(); \ -+ break; \ -+ \ -+ case OPT_NO_SELF_CONFINEMENT: \ -+ daemon_disable_self_confinement(); \ -+ break; \ -+ \ -+ case OPT_NO_CHDIR: \ -+ break; \ -+ \ -+ case OPT_PIDFILE: \ -+ set_pidfile(optarg); \ -+ break; \ -+ \ -+ case OPT_PIPE_HANDLE: \ -+ set_pipe_handle(optarg); \ -+ break; \ -+ \ -+ case OPT_SERVICE: \ -+ set_detach(); \ -+ break; \ -+ \ -+ case OPT_SERVICE_MONITOR: \ -+ break; \ -+ \ -+ case OPT_USER_GROUP: \ -+ daemon_set_new_user(optarg); -+ -+#define DAEMON_OPTION_CASES \ -+ case OPT_DETACH: \ -+ case OPT_NO_SELF_CONFINEMENT: \ -+ case OPT_NO_CHDIR: \ -+ case OPT_PIDFILE: \ -+ case OPT_PIPE_HANDLE: \ -+ case OPT_SERVICE: \ -+ case OPT_SERVICE_MONITOR: \ -+ case OPT_USER_GROUP: -+ -+void control_handler(DWORD request); -+void set_pipe_handle(const char *pipe_handle); -+void set_detach(void); -+#endif /* _WIN32 */ -+ -+bool get_detach(void); -+void daemon_save_fd(int fd); -+void daemonize(void); -+void daemonize_start(bool access_datapath); -+void daemonize_complete(void); -+void daemon_set_new_user(const char * user_spec); -+void daemon_become_new_user(bool access_datapath); -+void daemon_usage(void); -+void daemon_disable_self_confinement(void); -+bool daemon_should_self_confine(void); -+void service_start(int *argcp, char **argvp[]); -+void service_stop(void); -+bool should_service_stop(void); -+void set_pidfile(const char *name); -+void close_standard_fds(void); -+ -+#endif /* daemon.h */ -Index: openvswitch-2.17.2/include/internal/db-ctl-base.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/db-ctl-base.h -@@ -0,0 +1,282 @@ -+/* -+ * Copyright (c) 2015, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef DB_CTL_BASE_H -+#define DB_CTL_BASE_H 1 -+ -+#include "openvswitch/compiler.h" -+#include "openvswitch/dynamic-string.h" -+#include "openvswitch/shash.h" -+ -+struct ctl_context; -+struct option; -+struct ovsdb_idl; -+struct ovsdb_idl_row; -+struct ovsdb_idl_txn; -+struct ovsdb_symbol_table; -+struct table; -+ -+/* This library module contains the common parts for ovsdb manipulation -+ * (structs, commands and functions). To utilize this module, user must -+ * define the following: -+ * -+ * - the command syntaxes for each command. (See 'struct ctl_command_syntax' -+ * for more info) and regiters them using ctl_register_commands(). -+ * -+ * - the *ctl command context by inheriting the 'struct ctl_context' for -+ * additional commands implemented by user. (See 'struct ctl_context' for -+ * more info) -+*/ -+ -+/* ctl_fatal() also logs the error, so it is preferred in this file. */ -+#define ovs_fatal please_use_ctl_fatal_instead_of_ovs_fatal -+ -+struct ctl_table_class; -+struct ovsdb_idl_class; -+struct ovsdb_idl_table_class; -+struct cmd_show_table; -+ -+/* ctl_init() figures out the number of tables on its own and flags an error if -+ * 'ctl_classes' was defined with the wrong number of elements. */ -+#define ctl_init(idl_class, table_classes, ctl_classes, cmd_show_table, \ -+ ctl_exit_func) \ -+ (BUILD_ASSERT(ARRAY_SIZE(table_classes) == ARRAY_SIZE(ctl_classes)), \ -+ ctl_init__(idl_class, ctl_classes, cmd_show_table, ctl_exit_func)) -+void ctl_init__(const struct ovsdb_idl_class *, const struct ctl_table_class *, -+ const struct cmd_show_table *cmd_show_tables, -+ void (*ctl_exit_func)(int status)); -+char *ctl_default_db(void); -+void ctl_error(struct ctl_context *, const char *, ...) -+OVS_PRINTF_FORMAT(2, 3); -+OVS_NO_RETURN void ctl_fatal(const char *, ...) OVS_PRINTF_FORMAT(1, 2); -+ -+/* *ctl command syntax structure, to be defined by each command implementation. -+ * -+ * Execution Path -+ * ============== -+ * -+ * Three stylized functions accompany each of these data structures: -+ * -+ * "pre-run" "run" "post-run" -+ * --------------- ------------ ----------------- -+ * *ctl ->prerequisites ->run ->postprocess -+ * -+ * Any *ctl command implementation should go through the following execution -+ * path: -+ * -+ * 1. parses user command-line input and finds the corresponding syntax -+ * structures. -+ * -+ * 2. calls prerequisites() for getting the columns or tables used by each -+ * command. -+ * -+ * 3. calls run() to execute each command and to generate output. -+ * -+ * 4. calls postprocess() after output has been committed. (Only needed -+ * by 'create' command sofar) -+ * -+ * Execution Context -+ * ================= -+ * -+ * Each of the stylized functions requires the 'struct ctl_context' as input -+ * to provide context e.g. command-line arguments, table to be modified. User -+ * may define more specific context (by inheriting 'struct ctl_context') and -+ * write stylized functions that use it. In that case, CONTAINER_OF() can -+ * be used to cast the generic context to the specific one. -+ * -+ * */ -+struct ctl_command_syntax { -+ const char *name; /* e.g. "add-br" */ -+ int min_args; /* Min number of arguments following name. */ -+ int max_args; /* Max number of arguments following name. */ -+ -+ /* Names that roughly describe the arguments that the command -+ * uses. These should be similar to the names displayed in the -+ * man page or in the help output. */ -+ const char *arguments; -+ -+ /* If nonnull, calls ovsdb_idl_add_column() or ovsdb_idl_add_table() for -+ * each column or table in ctx->idl that it uses. */ -+ void (*prerequisites)(struct ctl_context *ctx); -+ -+ /* Does the actual work of the command and puts the command's output, if -+ * any, in ctx->output or ctx->table. -+ * -+ * Alternatively, if some prerequisite of the command is not met and the -+ * caller should wait for something to change and then retry, it may set -+ * ctx->try_again to true. (Only the "wait-until" command currently does -+ * this.) */ -+ void (*run)(struct ctl_context *ctx); -+ -+ /* If nonnull, called after the transaction has been successfully -+ * committed. ctx->output is the output from the "run" function, which -+ * this function may modify and otherwise postprocess as needed. (Only the -+ * "create" command currently does any postprocessing.) */ -+ void (*postprocess)(struct ctl_context *ctx); -+ -+ /* A comma-separated list of supported options, e.g. "--a,--b", or the -+ * empty string if the command does not support any options. -+ * -+ * Arguments are determined by appending special characters to option -+ * names: -+ * -+ * - Append "=" (e.g. "--id=") for a required argument. -+ * -+ * - Append "?" (e.g. "--ovs?") for an optional argument. -+ * -+ * - Otherwise an option does not accept an argument. */ -+ const char *options; -+ -+ enum { RO, RW } mode; /* Does this command modify the database? */ -+}; -+ -+/* A command extracted from command-line input plus the structs for -+ * output generation. */ -+struct ctl_command { -+ /* Data that remains constant after initialization. */ -+ const struct ctl_command_syntax *syntax; -+ int argc; -+ char **argv; -+ struct shash options; -+ -+ /* Data modified by commands. */ -+ struct ds output; -+ struct table *table; -+}; -+ -+bool ctl_might_write_to_db(const struct ctl_command *, size_t n); -+const char *ctl_get_db_cmd_usage(void); -+ -+const char *ctl_list_db_tables_usage(void); -+void ctl_print_commands(void); -+void ctl_print_options(const struct option *); -+void ctl_add_cmd_options(struct option **, size_t *n_options_p, -+ size_t *allocated_options_p, int opt_val); -+void ctl_register_commands(const struct ctl_command_syntax *); -+char * OVS_WARN_UNUSED_RESULT ctl_parse_commands( -+ int argc, char *argv[], struct shash *local_options, -+ struct ctl_command **commandsp, size_t *n_commandsp); -+ -+/* Sometimes, it is desirable to print the table with weak reference to -+ * rows in a 'cmd_show_table' table. In that case, the 'weak_ref_table' -+ * should be used and user must define all variables. */ -+struct weak_ref_table { -+ const struct ovsdb_idl_table_class *table; -+ const struct ovsdb_idl_column *name_column; -+ /* This colum must be a weak reference to the owning -+ * 'struct cmd_show_table''s table row. */ -+ const struct ovsdb_idl_column *wref_column; -+}; -+ -+/* This struct is for organizing the 'show' command output where: -+ * -+ * - 'table' is the table to show. -+ * -+ * - if 'name_column' is not null, it is used as the name for each row -+ * in 'table'. -+ * -+ * - 'columns[]' allows user to specify the print of additional columns -+ * in 'table'. -+ * -+ * - if 'wref_table' is populated, print 'wref_table.name_column' for -+ * each row in table 'wref_table.table' that has a reference to 'table' -+ * in 'wref_table.wref_column'. Every field must be populated. -+ * -+ * */ -+struct cmd_show_table { -+ const struct ovsdb_idl_table_class *table; -+ const struct ovsdb_idl_column *name_column; -+ const struct ovsdb_idl_column *columns[4]; /* Seems like a good number. */ -+ const struct weak_ref_table wref_table; -+}; -+ -+ -+/* The base context struct for conducting the common database -+ * operations (commands listed in 'db_ctl_commands'). User should -+ * define the per-schema context by inheriting this struct as base. -+ * -+ * Database Caches -+ * =============== -+ * -+ * User may implement caches for contents of the database to facilitate -+ * specific commands. In that case, the common commands defined in -+ * 'db_ctl_commands' that may invalidate the cache must call the -+ * invalidate_cache(). -+ * -+ **/ -+struct ctl_context { -+ /* Read-only. */ -+ int argc; -+ char **argv; -+ struct shash options; -+ -+ /* Modifiable state. */ -+ char *error; -+ struct ds output; -+ struct table *table; -+ struct ovsdb_idl *idl; -+ struct ovsdb_idl_txn *txn; -+ struct ovsdb_symbol_table *symtab; -+ -+ /* For implementation with a cache of the contents of the database, -+ * this function will be called when the database is changed and the -+ * change makes the cache no longer valid. */ -+ void (*invalidate_cache_cb)(struct ctl_context *); -+ -+ /* A command may set this member to true if some prerequisite is not met -+ * and the caller should wait for something to change and then retry. */ -+ bool try_again; -+}; -+ -+void ctl_context_init_command(struct ctl_context *, struct ctl_command *); -+void ctl_context_init(struct ctl_context *, struct ctl_command *, -+ struct ovsdb_idl *, struct ovsdb_idl_txn *, -+ struct ovsdb_symbol_table *, -+ void (*invalidate_cache)(struct ctl_context *)); -+void ctl_context_done_command(struct ctl_context *, struct ctl_command *); -+void ctl_context_done(struct ctl_context *, struct ctl_command *); -+ -+/* A way to identify a particular row in the database based on a user-provided -+ * string. If all fields are NULL, the struct is ignored. Otherwise, -+ * 'name_column' designates a column whose table is searched for rows that -+ * match with the user string. If 'key' is NULL, then 'name_column' should be -+ * a string or integer-valued column; otherwise it should be a map from a -+ * string to one of those types and the value corresponding to 'key' is what is -+ * matched. If a matching row is found, then: -+ * -+ * - If 'uuid_column' is NULL, the matching row is the final row. -+ * -+ * - Otherwise 'uuid_column' must designate a UUID-typed column whose value -+ * refers to exactly one row, which is the final row. -+ */ -+struct ctl_row_id { -+ const struct ovsdb_idl_column *name_column; -+ const char *key; -+ const struct ovsdb_idl_column *uuid_column; -+}; -+ -+struct ctl_table_class { -+ struct ctl_row_id row_ids[4]; -+}; -+ -+char *ctl_get_row(struct ctl_context *, const struct ovsdb_idl_table_class *, -+ const char *record_id, bool must_exist, -+ const struct ovsdb_idl_row **); -+ -+char *ctl_set_column(const char *table_name, const struct ovsdb_idl_row *, -+ const char *arg, struct ovsdb_symbol_table *); -+ -+#endif /* db-ctl-base.h */ -Index: openvswitch-2.17.2/include/internal/dhparams.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/dhparams.h -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (c) 2008, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef DHPARAMS_H -+#define DHPARAMS_H 1 -+ -+#include -+#include -+ -+DH *get_dh2048(void); -+DH *get_dh4096(void); -+ -+#endif /* dhparams.h */ -Index: openvswitch-2.17.2/include/internal/dirs.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/dirs.h -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef DIRS_H -+#define DIRS_H 1 -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+const char *ovs_sysconfdir(void); /* /usr/local/etc */ -+const char *ovs_pkgdatadir(void); /* /usr/local/share/openvswitch */ -+const char *ovs_rundir(void); /* /usr/local/var/run/openvswitch */ -+const char *ovs_logdir(void); /* /usr/local/var/log/openvswitch */ -+const char *ovs_dbdir(void); /* /usr/local/etc/openvswitch */ -+const char *ovs_bindir(void); /* /usr/local/bin */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* dirs.h */ -Index: openvswitch-2.17.2/include/internal/fatal-signal.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/fatal-signal.h -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2013 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef FATAL_SIGNAL_H -+#define FATAL_SIGNAL_H 1 -+ -+#ifndef _WIN32 -+#include -+#endif -+#include -+ -+/* Basic interface. */ -+void fatal_signal_init(void); -+void fatal_signal_add_hook(void (*hook_cb)(void *aux), -+ void (*cancel_cb)(void *aux), void *aux, -+ bool run_at_exit); -+void fatal_signal_fork(void); -+void fatal_signal_run(void); -+void fatal_signal_wait(void); -+void fatal_ignore_sigpipe(void); -+void fatal_signal_atexit_handler(void); -+ -+/* Convenience functions for unlinking files upon termination. -+ * -+ * These functions also unlink the files upon normal process termination via -+ * exit(). */ -+void fatal_signal_add_file_to_unlink(const char *); -+void fatal_signal_remove_file_to_unlink(const char *); -+int fatal_signal_unlink_file_now(const char *); -+ -+/* Interface for other code that catches one of our signals and needs to pass -+ * it through. */ -+void fatal_signal_handler(int sig_nr); -+ -+#ifndef _WIN32 -+void fatal_signal_block(sigset_t *prev_mask); -+#endif -+ -+#endif /* fatal-signal.h */ -Index: openvswitch-2.17.2/include/internal/hash-aarch64.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/hash-aarch64.h -@@ -0,0 +1,150 @@ -+/* -+ * Copyright (c) 2019 Arm Limited -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements HASH operation primitives on aarch64. */ -+#ifndef HASH_AARCH64_H -+#define HASH_AARCH64_H 1 -+ -+#ifndef HASH_H -+#error "This header should only be included indirectly via hash.h." -+#endif -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#include -+ -+static inline uint32_t hash_add(uint32_t hash, uint32_t data) -+{ -+ return __crc32cw(hash, data); -+} -+ -+/* Add the halves of 'data' in the memory order. */ -+static inline uint32_t hash_add64(uint32_t hash, uint64_t data) -+{ -+ return __crc32cd(hash, data); -+} -+ -+static inline uint32_t hash_finish(uint32_t hash, uint64_t final) -+{ -+ /* The finishing multiplier 0x805204f3 has been experimentally -+ * derived to pass the testsuite hash tests. */ -+ hash = __crc32cd(hash, final) * 0x805204f3; -+ return hash ^ hash >> 16; /* Increase entropy in LSBs. */ -+} -+ -+/* Returns the hash of the 'n' 32-bit words at 'p_', starting from 'basis'. -+ * We access 'p_' as a uint64_t pointer. -+ * -+ * This is inlined for the compiler to have access to the 'n_words', which -+ * in many cases is a constant. */ -+static inline uint32_t -+hash_words_inline(const uint32_t p_[], size_t n_words, uint32_t basis) -+{ -+ const uint64_t *p = (const void *)p_; -+ uint32_t hash1 = basis; -+ uint32_t hash2 = 0; -+ uint32_t hash3 = n_words; -+ const uint32_t *endp = (const uint32_t *)p + n_words; -+ const uint64_t *limit = p + n_words / 2 - 3; -+ -+ while (p <= limit) { -+ hash1 = __crc32cd(hash1, p[0]); -+ hash2 = __crc32cd(hash2, p[1]); -+ hash3 = __crc32cd(hash3, p[2]); -+ p += 3; -+ } -+ switch (endp - (const uint32_t *)p) { -+ case 1: -+ hash1 = __crc32cw(hash1, *(const uint32_t *)&p[0]); -+ break; -+ case 2: -+ hash1 = __crc32cd(hash1, p[0]); -+ break; -+ case 3: -+ hash1 = __crc32cd(hash1, p[0]); -+ hash2 = __crc32cw(hash2, *(const uint32_t *)&p[1]); -+ break; -+ case 4: -+ hash1 = __crc32cd(hash1, p[0]); -+ hash2 = __crc32cd(hash2, p[1]); -+ break; -+ case 5: -+ hash1 = __crc32cd(hash1, p[0]); -+ hash2 = __crc32cd(hash2, p[1]); -+ hash3 = __crc32cw(hash3, *(const uint32_t *)&p[2]); -+ break; -+ } -+ return hash_finish(hash1, (uint64_t)hash2 << 32 | hash3); -+} -+ -+/* A simpler version for 64-bit data. -+ * 'n_words' is the count of 64-bit words, basis is 64 bits. */ -+static inline uint32_t -+hash_words64_inline(const uint64_t p[], size_t n_words, uint32_t basis) -+{ -+ uint32_t hash1 = basis; -+ uint32_t hash2 = 0; -+ uint32_t hash3 = n_words; -+ const uint64_t *endp = p + n_words; -+ const uint64_t *limit = endp - 3; -+ -+ while (p <= limit) { -+ hash1 = __crc32cd(hash1, p[0]); -+ hash2 = __crc32cd(hash2, p[1]); -+ hash3 = __crc32cd(hash3, p[2]); -+ p += 3; -+ } -+ switch (endp - p) { -+ case 1: -+ hash1 = __crc32cd(hash1, p[0]); -+ break; -+ case 2: -+ hash1 = __crc32cd(hash1, p[0]); -+ hash2 = __crc32cd(hash2, p[1]); -+ break; -+ } -+ return hash_finish(hash1, (uint64_t)hash2 << 32 | hash3); -+} -+ -+static inline uint32_t hash_uint64_basis(const uint64_t x, -+ const uint32_t basis) -+{ -+ /* '23' chosen to mix bits enough for the test-hash to pass. */ -+ return hash_finish(hash_add64(basis, x), 23); -+} -+ -+static inline uint32_t hash_uint64(const uint64_t x) -+{ -+ return hash_uint64_basis(x, 0); -+} -+ -+static inline uint32_t hash_2words(uint32_t x, uint32_t y) -+{ -+ return hash_uint64((uint64_t)y << 32 | x); -+} -+ -+static inline uint32_t hash_pointer(const void *p, uint32_t basis) -+{ -+ return hash_uint64_basis((uint64_t) (uintptr_t) p, basis); -+} -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* hash-aarch64.h */ -Index: openvswitch-2.17.2/include/internal/hmapx.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/hmapx.h -@@ -0,0 +1,86 @@ -+/* -+ * Copyright (c) 2011, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef HMAPX_H -+#define HMAPX_H -+ -+#include "openvswitch/hmap.h" -+ -+struct hmapx_node { -+ struct hmap_node hmap_node; -+ void *data; -+}; -+ -+/* A set of "void *" pointers. */ -+struct hmapx { -+ struct hmap map; -+}; -+ -+#define HMAPX_INITIALIZER(HMAPX) { HMAP_INITIALIZER(&(HMAPX)->map) } -+ -+/* Basics. */ -+void hmapx_init(struct hmapx *); -+void hmapx_destroy(struct hmapx *); -+void hmapx_clone(struct hmapx *, const struct hmapx *); -+void hmapx_swap(struct hmapx *, struct hmapx *); -+void hmapx_moved(struct hmapx *); -+ -+/* Count. */ -+bool hmapx_is_empty(const struct hmapx *); -+size_t hmapx_count(const struct hmapx *); -+ -+/* Insertion. */ -+struct hmapx_node *hmapx_add(struct hmapx *, void *); -+void hmapx_add_assert(struct hmapx *, void *); -+ -+/* Deletion. */ -+void hmapx_clear(struct hmapx *); -+void hmapx_delete(struct hmapx *, struct hmapx_node *); -+bool hmapx_find_and_delete(struct hmapx *, const void *); -+void hmapx_find_and_delete_assert(struct hmapx *, const void *); -+ -+/* Search. */ -+struct hmapx_node *hmapx_find(const struct hmapx *, const void *); -+bool hmapx_contains(const struct hmapx *, const void *); -+bool hmapx_equals(const struct hmapx *, const struct hmapx *); -+ -+/* Iteration. */ -+ -+/* Iterates through every hmapx_node in HMAPX. */ -+#define HMAPX_FOR_EACH(NODE, HMAPX) \ -+ HMAP_FOR_EACH_INIT(NODE, hmap_node, &(HMAPX)->map, \ -+ BUILD_ASSERT_TYPE(NODE, struct hmapx_node *), \ -+ BUILD_ASSERT_TYPE(HMAPX, struct hmapx *)) -+ -+/* Safe when NODE may be freed (not needed when NODE may be removed from the -+ * hash map but its members remain accessible and intact). */ -+#define HMAPX_FOR_EACH_SAFE_SHORT(NODE, HMAPX) \ -+ HMAP_FOR_EACH_SAFE_SHORT_INIT (NODE, hmap_node, &(HMAPX)->map, \ -+ BUILD_ASSERT_TYPE(NODE, struct hmapx_node *), \ -+ BUILD_ASSERT_TYPE(HMAPX, struct hmapx *)) -+ -+#define HMAPX_FOR_EACH_SAFE_LONG(NODE, NEXT, HMAPX) \ -+ HMAP_FOR_EACH_SAFE_LONG_INIT (NODE, NEXT, hmap_node, &(HMAPX)->map, \ -+ BUILD_ASSERT_TYPE(NODE, struct hmapx_node *), \ -+ BUILD_ASSERT_TYPE(NEXT, struct hmapx_node *), \ -+ BUILD_ASSERT_TYPE(HMAPX, struct hmapx *)) -+ -+#define HMAPX_FOR_EACH_SAFE(...) \ -+ OVERLOAD_SAFE_MACRO(HMAPX_FOR_EACH_SAFE_LONG, \ -+ HMAPX_FOR_EACH_SAFE_SHORT, \ -+ 3, __VA_ARGS__) -+ -+#endif /* hmapx.h */ -Index: openvswitch-2.17.2/include/internal/id-pool.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/id-pool.h -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (c) 2014 Nicira, Inc. -+ * Copyright (c) 2014 Netronome. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef ID_POOL_H -+#define ID_POOL_H -+ -+#include -+#include -+#include -+ -+struct id_pool; -+ -+struct id_pool *id_pool_create(uint32_t base, uint32_t n_ids); -+void id_pool_destroy(struct id_pool *); -+bool id_pool_alloc_id(struct id_pool *, uint32_t *id); -+void id_pool_free_id(struct id_pool *, uint32_t id); -+void id_pool_add(struct id_pool *, uint32_t id); -+ -+/* -+ * ID pool. -+ * ======== -+ * -+ * Pool of unique 32bit ids. -+ * Allocation always returns the lowest available id. -+ * -+ * Thread-safety -+ * ============= -+ * -+ * APIs are not thread safe. -+ */ -+#endif /* id-pool.h */ -Index: openvswitch-2.17.2/include/internal/jsonrpc.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/jsonrpc.h -@@ -0,0 +1,153 @@ -+/* -+ * Copyright (c) 2009, 2010, 2012, 2013, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef JSONRPC_H -+#define JSONRPC_H 1 -+ -+/* This is an implementation of the JSON-RPC 1.0 specification defined at -+ * http://json-rpc.org/wiki/specification. */ -+ -+#include -+#include -+#include "openvswitch/types.h" -+ -+struct json; -+struct jsonrpc_msg; -+struct pstream; -+struct reconnect_stats; -+struct stream; -+struct svec; -+ -+/* API for a JSON-RPC stream. */ -+ -+/* Default port numbers. -+ * -+ * OVSDB_OLD_PORT defines the original port number used by OVS. -+ * OVSDB_PORT defines the official port number assigned by IANA. */ -+#define OVSDB_OLD_PORT 6632 -+#define OVSDB_PORT 6640 -+ -+int jsonrpc_stream_open(const char *name, struct stream **, uint8_t dscp); -+int jsonrpc_pstream_open(const char *name, struct pstream **, uint8_t dscp); -+ -+struct jsonrpc *jsonrpc_open(struct stream *); -+void jsonrpc_close(struct jsonrpc *); -+ -+void jsonrpc_run(struct jsonrpc *); -+void jsonrpc_wait(struct jsonrpc *); -+ -+int jsonrpc_get_status(const struct jsonrpc *); -+size_t jsonrpc_get_backlog(const struct jsonrpc *); -+void jsonrpc_set_backlog_threshold(struct jsonrpc *, size_t max_n_msgs, -+ size_t max_backlog_bytes); -+ -+unsigned int jsonrpc_get_received_bytes(const struct jsonrpc *); -+const char *jsonrpc_get_name(const struct jsonrpc *); -+ -+int jsonrpc_send(struct jsonrpc *, struct jsonrpc_msg *); -+int jsonrpc_recv(struct jsonrpc *, struct jsonrpc_msg **); -+void jsonrpc_recv_wait(struct jsonrpc *); -+ -+int jsonrpc_send_block(struct jsonrpc *, struct jsonrpc_msg *); -+int jsonrpc_recv_block(struct jsonrpc *, struct jsonrpc_msg **); -+int jsonrpc_transact_block(struct jsonrpc *, struct jsonrpc_msg *, -+ struct jsonrpc_msg **); -+ -+/* Messages. */ -+enum jsonrpc_msg_type { -+ JSONRPC_REQUEST, /* Request. */ -+ JSONRPC_NOTIFY, /* Notification. */ -+ JSONRPC_REPLY, /* Successful reply. */ -+ JSONRPC_ERROR /* Error reply. */ -+}; -+ -+struct jsonrpc_msg { -+ enum jsonrpc_msg_type type; -+ char *method; /* Request or notification only. */ -+ struct json *params; /* Request or notification only. */ -+ struct json *result; /* Successful reply only. */ -+ struct json *error; /* Error reply only. */ -+ struct json *id; /* Request or reply only. */ -+}; -+ -+struct jsonrpc_msg *jsonrpc_create_request(const char *method, -+ struct json *params, -+ struct json **idp); -+struct jsonrpc_msg *jsonrpc_create_notify(const char *method, -+ struct json *params); -+struct jsonrpc_msg *jsonrpc_create_reply(struct json *result, -+ const struct json *id); -+struct jsonrpc_msg *jsonrpc_create_error(struct json *error, -+ const struct json *id); -+ -+struct jsonrpc_msg *jsonrpc_msg_clone(const struct jsonrpc_msg *); -+ -+const char *jsonrpc_msg_type_to_string(enum jsonrpc_msg_type); -+char *jsonrpc_msg_is_valid(const struct jsonrpc_msg *); -+void jsonrpc_msg_destroy(struct jsonrpc_msg *); -+ -+char *jsonrpc_msg_from_json(struct json *, struct jsonrpc_msg **); -+struct json *jsonrpc_msg_to_json(struct jsonrpc_msg *); -+ -+char *jsonrpc_msg_to_string(const struct jsonrpc_msg *); -+ -+/* A JSON-RPC session with reconnection. */ -+ -+struct jsonrpc_session *jsonrpc_session_open(const char *name, bool retry); -+struct jsonrpc_session *jsonrpc_session_open_multiple(const struct svec *, -+ bool retry); -+struct jsonrpc_session *jsonrpc_session_open_unreliably(struct jsonrpc *, -+ uint8_t); -+void jsonrpc_session_close(struct jsonrpc_session *); -+ -+struct jsonrpc *jsonrpc_session_steal(struct jsonrpc_session *); -+void jsonrpc_session_replace(struct jsonrpc_session *, struct jsonrpc *); -+ -+void jsonrpc_session_run(struct jsonrpc_session *); -+void jsonrpc_session_wait(struct jsonrpc_session *); -+ -+size_t jsonrpc_session_get_backlog(const struct jsonrpc_session *); -+const char *jsonrpc_session_get_name(const struct jsonrpc_session *); -+size_t jsonrpc_session_get_n_remotes(const struct jsonrpc_session *); -+ -+int jsonrpc_session_send(struct jsonrpc_session *, struct jsonrpc_msg *); -+struct jsonrpc_msg *jsonrpc_session_recv(struct jsonrpc_session *); -+void jsonrpc_session_recv_wait(struct jsonrpc_session *); -+ -+bool jsonrpc_session_is_alive(const struct jsonrpc_session *); -+bool jsonrpc_session_is_connected(const struct jsonrpc_session *); -+unsigned int jsonrpc_session_get_seqno(const struct jsonrpc_session *); -+int jsonrpc_session_get_status(const struct jsonrpc_session *); -+int jsonrpc_session_get_last_error(const struct jsonrpc_session *); -+void jsonrpc_session_get_reconnect_stats(const struct jsonrpc_session *, -+ struct reconnect_stats *); -+ -+void jsonrpc_session_enable_reconnect(struct jsonrpc_session *); -+void jsonrpc_session_force_reconnect(struct jsonrpc_session *); -+void jsonrpc_session_reset_backoff(struct jsonrpc_session *); -+ -+void jsonrpc_session_set_max_backoff(struct jsonrpc_session *, -+ int max_backoff); -+void jsonrpc_session_set_probe_interval(struct jsonrpc_session *, -+ int probe_interval); -+void jsonrpc_session_set_dscp(struct jsonrpc_session *, -+ uint8_t dscp); -+void jsonrpc_session_set_backlog_threshold(struct jsonrpc_session *, -+ size_t max_n_msgs, -+ size_t max_backlog_bytes); -+const char *jsonrpc_session_get_id(const struct jsonrpc_session *); -+ -+#endif /* jsonrpc.h */ -Index: openvswitch-2.17.2/include/internal/memory.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/memory.h -@@ -0,0 +1,60 @@ -+/* -+ * Copyright (c) 2012 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef MEMORY_H -+#define MEMORY_H 1 -+ -+/* Memory usage monitor. -+ * -+ * This is intended to be called as part of a daemon's main loop. After some -+ * time to allow the daemon to allocate an initial memory usage, it logs some -+ * memory usage information (most of which must actually be provided by the -+ * client). At intervals, if the daemon's memory usage has grown -+ * significantly, it again logs information. -+ * -+ * The monitor also has a unixctl interface. -+ * -+ * Intended usage in the program's main loop is like this: -+ * -+ * for (;;) { -+ * memory_run(); -+ * if (memory_should_report()) { -+ * struct simap usage; -+ * -+ * simap_init(&usage); -+ * ...fill in 'usage' with meaningful statistics... -+ * memory_report(&usage); -+ * simap_destroy(&usage); -+ * } -+ * -+ * ... -+ * -+ * memory_wait(); -+ * poll_block(); -+ * } -+ */ -+ -+#include -+ -+struct simap; -+ -+void memory_run(void); -+void memory_wait(void); -+ -+bool memory_should_report(void); -+void memory_report(const struct simap *usage); -+ -+#endif /* memory.h */ -Index: openvswitch-2.17.2/include/internal/netdev-afxdp.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/netdev-afxdp.h -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (c) 2018, 2019 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef NETDEV_AFXDP_H -+#define NETDEV_AFXDP_H 1 -+ -+#ifdef HAVE_AF_XDP -+ -+#include -+#include -+ -+/* These functions are Linux AF_XDP specific, so they should be used directly -+ * only by Linux-specific code. */ -+ -+enum afxdp_mode { -+ OVS_AF_XDP_MODE_UNSPEC, -+ OVS_AF_XDP_MODE_BEST_EFFORT, -+ OVS_AF_XDP_MODE_NATIVE_ZC, -+ OVS_AF_XDP_MODE_NATIVE, -+ OVS_AF_XDP_MODE_GENERIC, -+ OVS_AF_XDP_MODE_MAX, -+}; -+ -+struct dp_packet; -+struct dp_packet_batch; -+struct netdev; -+struct netdev_afxdp_tx_lock; -+struct netdev_custom_stats; -+struct netdev_rxq; -+struct netdev_stats; -+struct smap; -+struct xdp_umem; -+struct xsk_socket_info; -+ -+int netdev_afxdp_rxq_construct(struct netdev_rxq *rxq_); -+void netdev_afxdp_rxq_destruct(struct netdev_rxq *rxq_); -+int netdev_afxdp_init(void); -+int netdev_afxdp_construct(struct netdev *netdev_); -+void netdev_afxdp_destruct(struct netdev *netdev_); -+int netdev_afxdp_verify_mtu_size(const struct netdev *netdev, int mtu); -+ -+int netdev_afxdp_rxq_recv(struct netdev_rxq *rxq_, -+ struct dp_packet_batch *batch, -+ int *qfill); -+int netdev_afxdp_batch_send(struct netdev *netdev_, int qid, -+ struct dp_packet_batch *batch, -+ bool concurrent_txq); -+int netdev_afxdp_set_config(struct netdev *netdev, const struct smap *args, -+ char **errp); -+int netdev_afxdp_get_config(const struct netdev *netdev, struct smap *args); -+int netdev_afxdp_get_stats(const struct netdev *netdev_, -+ struct netdev_stats *stats); -+int netdev_afxdp_get_custom_stats(const struct netdev *netdev, -+ struct netdev_custom_stats *custom_stats); -+ -+ -+void free_afxdp_buf(struct dp_packet *p); -+int netdev_afxdp_reconfigure(struct netdev *netdev); -+void signal_remove_xdp(struct netdev *netdev); -+ -+#else /* !HAVE_AF_XDP */ -+ -+#include "openvswitch/compiler.h" -+ -+struct dp_packet; -+ -+static inline void -+free_afxdp_buf(struct dp_packet *p OVS_UNUSED) -+{ -+ /* Nothing. */ -+} -+ -+#endif /* HAVE_AF_XDP */ -+#endif /* netdev-afxdp.h */ -Index: openvswitch-2.17.2/include/internal/netdev-dpdk.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/netdev-dpdk.h -@@ -0,0 +1,165 @@ -+/* -+ * Copyright (c) 2014, 2015, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef NETDEV_DPDK_H -+#define NETDEV_DPDK_H -+ -+#include -+ -+#include "openvswitch/compiler.h" -+ -+struct dp_packet; -+struct netdev; -+ -+#ifdef DPDK_NETDEV -+ -+#include -+ -+void netdev_dpdk_register(void); -+void free_dpdk_buf(struct dp_packet *); -+ -+bool netdev_dpdk_flow_api_supported(struct netdev *); -+ -+int -+netdev_dpdk_rte_flow_destroy(struct netdev *netdev, -+ struct rte_flow *rte_flow, -+ struct rte_flow_error *error); -+struct rte_flow * -+netdev_dpdk_rte_flow_create(struct netdev *netdev, -+ const struct rte_flow_attr *attr, -+ const struct rte_flow_item *items, -+ const struct rte_flow_action *actions, -+ struct rte_flow_error *error); -+int -+netdev_dpdk_rte_flow_query_count(struct netdev *netdev, -+ struct rte_flow *rte_flow, -+ struct rte_flow_query_count *query, -+ struct rte_flow_error *error); -+int -+netdev_dpdk_get_port_id(struct netdev *netdev); -+ -+#ifdef ALLOW_EXPERIMENTAL_API -+ -+int netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *, -+ struct rte_flow_tunnel *, -+ struct rte_flow_action **, -+ uint32_t *num_of_actions, -+ struct rte_flow_error *); -+int netdev_dpdk_rte_flow_tunnel_match(struct netdev *, -+ struct rte_flow_tunnel *, -+ struct rte_flow_item **, -+ uint32_t *num_of_items, -+ struct rte_flow_error *); -+int netdev_dpdk_rte_flow_get_restore_info(struct netdev *, -+ struct dp_packet *, -+ struct rte_flow_restore_info *, -+ struct rte_flow_error *); -+int netdev_dpdk_rte_flow_tunnel_action_decap_release(struct netdev *, -+ struct rte_flow_action *, -+ uint32_t num_of_actions, -+ struct rte_flow_error *); -+int netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *, -+ struct rte_flow_item *, -+ uint32_t num_of_items, -+ struct rte_flow_error *); -+ -+#else -+ -+static inline void -+set_error(struct rte_flow_error *error, enum rte_flow_error_type type) -+{ -+ if (!error) { -+ return; -+ } -+ error->type = type; -+ error->cause = NULL; -+ error->message = NULL; -+} -+ -+static inline int -+netdev_dpdk_rte_flow_tunnel_decap_set( -+ struct netdev *netdev OVS_UNUSED, -+ struct rte_flow_tunnel *tunnel OVS_UNUSED, -+ struct rte_flow_action **actions OVS_UNUSED, -+ uint32_t *num_of_actions OVS_UNUSED, -+ struct rte_flow_error *error) -+{ -+ set_error(error, RTE_FLOW_ERROR_TYPE_ACTION); -+ return -1; -+} -+ -+static inline int -+netdev_dpdk_rte_flow_tunnel_match(struct netdev *netdev OVS_UNUSED, -+ struct rte_flow_tunnel *tunnel OVS_UNUSED, -+ struct rte_flow_item **items OVS_UNUSED, -+ uint32_t *num_of_items OVS_UNUSED, -+ struct rte_flow_error *error) -+{ -+ set_error(error, RTE_FLOW_ERROR_TYPE_ITEM); -+ return -1; -+} -+ -+static inline int -+netdev_dpdk_rte_flow_get_restore_info( -+ struct netdev *netdev OVS_UNUSED, -+ struct dp_packet *p OVS_UNUSED, -+ struct rte_flow_restore_info *info OVS_UNUSED, -+ struct rte_flow_error *error) -+{ -+ set_error(error, RTE_FLOW_ERROR_TYPE_ATTR); -+ return -1; -+} -+ -+static inline int -+netdev_dpdk_rte_flow_tunnel_action_decap_release( -+ struct netdev *netdev OVS_UNUSED, -+ struct rte_flow_action *actions OVS_UNUSED, -+ uint32_t num_of_actions OVS_UNUSED, -+ struct rte_flow_error *error) -+{ -+ set_error(error, RTE_FLOW_ERROR_TYPE_NONE); -+ return 0; -+} -+ -+static inline int -+netdev_dpdk_rte_flow_tunnel_item_release( -+ struct netdev *netdev OVS_UNUSED, -+ struct rte_flow_item *items OVS_UNUSED, -+ uint32_t num_of_items OVS_UNUSED, -+ struct rte_flow_error *error) -+{ -+ set_error(error, RTE_FLOW_ERROR_TYPE_NONE); -+ return 0; -+} -+ -+#endif /* ALLOW_EXPERIMENTAL_API */ -+ -+#else -+ -+static inline void -+netdev_dpdk_register(void) -+{ -+ /* Nothing */ -+} -+static inline void -+free_dpdk_buf(struct dp_packet *buf OVS_UNUSED) -+{ -+ /* Nothing */ -+} -+ -+#endif -+ -+#endif /* netdev-dpdk.h */ -Index: openvswitch-2.17.2/include/internal/ovs-atomic-c++.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-c++.h -@@ -0,0 +1,67 @@ -+/* This header implements atomic operation primitives on compilers that -+ * have built-in support for ++C11 */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#include -+ -+#define ATOMIC(TYPE) std::atomic -+ -+using std::atomic_init; -+ -+using std::memory_order_relaxed; -+using std::memory_order_consume; -+using std::memory_order_acquire; -+using std::memory_order_release; -+using std::memory_order_acq_rel; -+using std::memory_order_seq_cst; -+ -+using std::atomic_thread_fence; -+using std::atomic_signal_fence; -+using std::atomic_is_lock_free; -+ -+using std::atomic_store; -+using std::atomic_store_explicit; -+ -+using std::atomic_compare_exchange_strong; -+using std::atomic_compare_exchange_strong_explicit; -+using std::atomic_compare_exchange_weak; -+using std::atomic_compare_exchange_weak_explicit; -+ -+using std::atomic_exchange; -+using std::atomic_exchange_explicit; -+ -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ (*(DST) = std::atomic_load_explicit(SRC, ORDER), \ -+ (void) 0) -+ -+#define atomic_add(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_sub(RMW, ARG, ORIG) \ -+ atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_or(RMW, ARG, ORIG) \ -+ atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_xor(RMW, ARG, ORIG) \ -+ atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_and(RMW, ARG, ORIG) \ -+ atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = (*(RMW)).fetch_add(ARG, ORDER), (void) 0) -+#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = (*(RMW)).fetch_sub(ARG, ORDER), (void) 0) -+#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = (*(RMW)).fetch_or(ARG, ORDER), (void) 0) -+#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = (*(RMW)).fetch_xor(ARG, ORDER), (void) 0) -+#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = (*(RMW)).fetch_and(ARG, ORDER), (void) 0) -+ -+using std::atomic_flag; -+using std::atomic_flag_test_and_set_explicit; -+using std::atomic_flag_test_and_set; -+using std::atomic_flag_clear_explicit; -+using std::atomic_flag_clear; -Index: openvswitch-2.17.2/include/internal/ovs-atomic-c11.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-c11.h -@@ -0,0 +1,54 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives on compilers that -+ * have built-in support for C11 */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#include -+ -+#define OMIT_STANDARD_ATOMIC_TYPES 1 -+#define ATOMIC(TYPE) _Atomic(TYPE) -+ -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ (*(DST) = atomic_load_explicit(SRC, ORDER), \ -+ (void) 0) -+ -+#define atomic_add(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_sub(RMW, ARG, ORIG) \ -+ atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_or(RMW, ARG, ORIG) \ -+ atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_xor(RMW, ARG, ORIG) \ -+ atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+#define atomic_and(RMW, ARG, ORIG) \ -+ atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = atomic_fetch_add_explicit(RMW, ARG, ORDER), (void) 0) -+#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = atomic_fetch_sub_explicit(RMW, ARG, ORDER), (void) 0) -+#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = atomic_fetch_or_explicit(RMW, ARG, ORDER), (void) 0) -+#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = atomic_fetch_xor_explicit(RMW, ARG, ORDER), (void) 0) -+#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -+ (*(ORIG) = atomic_fetch_and_explicit(RMW, ARG, ORDER), (void) 0) -Index: openvswitch-2.17.2/include/internal/ovs-atomic-flag-gcc4.7+.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-flag-gcc4.7+.h -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (c) 2013, 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic_flag on Clang and on GCC 4.7 and later. */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+/* atomic_flag */ -+ -+typedef struct { -+ unsigned char b; -+} atomic_flag; -+#define ATOMIC_FLAG_INIT { .b = false } -+ -+static inline bool -+atomic_flag_test_and_set_explicit(volatile atomic_flag *object, -+ memory_order order) -+{ -+ return __atomic_test_and_set(&object->b, order); -+} -+ -+static inline bool -+atomic_flag_test_and_set(volatile atomic_flag *object) -+{ -+ return atomic_flag_test_and_set_explicit(object, memory_order_seq_cst); -+} -+ -+static inline void -+atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order) -+{ -+ __atomic_clear(object, order); -+} -+ -+static inline void -+atomic_flag_clear(volatile atomic_flag *object) -+{ -+ atomic_flag_clear_explicit(object, memory_order_seq_cst); -+} -Index: openvswitch-2.17.2/include/internal/ovs-atomic-i586.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-i586.h -@@ -0,0 +1,489 @@ -+/* -+ * Copyright (c) 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives on 32-bit 586+ with GCC. -+ */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#define OVS_ATOMIC_I586_IMPL 1 -+ -+/* -+ * These assumptions have been adopted from the x86_64 Memory model: -+ * -+ * - 1, 2, and 4 byte loads and stores are atomic on aligned memory. -+ * - Loads are not reordered with other loads. -+ * - Stores are not reordered with OLDER loads. -+ * - Loads may be reordered with OLDER stores to a different memory location, -+ * but not with OLDER stores to the same memory location. -+ * - Stores are not reordered with other stores, except maybe for special -+ * instructions not emitted by compilers, or by the stores performed by -+ * a single fast string operation (e.g., "stos"). As long as the atomic -+ * stores are not combined with any other stores, even the allowed reordering -+ * of the stores by a single fast string operation is not a problem. -+ * - Neither loads nor stores are reordered with locked instructions. -+ * - Stores by a single processor are observed in the same order by all -+ * processors. -+ * - (Unlocked) Stores from different processors are NOT ordered. -+ * - Memory ordering obeys causality (memory ordering respects transitive -+ * visibility). -+ * - Any two stores are seen in a consistent order by processors other than -+ * the those performing the stores. -+ * - Locked instructions have total order. -+ * -+ * These rules imply that: -+ * -+ * - Locked instructions are not needed for aligned loads or stores to make -+ * them atomic for sizes upto 4 bytes. 8 byte objects need locked -+ * instructions. -+ * - All stores have release semantics; none of the preceding stores or loads -+ * can be reordered with following stores. Following loads could still be -+ * reordered to happen before the store, but that is not a violation of the -+ * release semantics. -+ * - All loads from a given memory location have acquire semantics with -+ * respect to the stores on the same memory location; none of the following -+ * loads or stores can be reordered with the load. Preceding stores to a -+ * different memory location MAY be reordered with the load, but that is not -+ * a violation of the acquire semantics (i.e., the loads and stores of two -+ * critical sections guarded by a different memory location can overlap). -+ * - Locked instructions serve as CPU memory barriers by themselves. -+ * - Locked stores implement the sequential consistency memory order. Using -+ * locked instructions when seq_cst memory order is requested allows normal -+ * loads to observe the stores in the same (total) order without using CPU -+ * memory barrier after the loads. -+ * -+ * NOTE: Some older AMD Opteron processors have a bug that violates the -+ * acquire semantics described above. The bug manifests as an unlocked -+ * read-modify-write operation following a "semaphore operation" operating -+ * on data that existed before entering the critical section; i.e., the -+ * preceding "semaphore operation" fails to function as an acquire barrier. -+ * The affected CPUs are AMD family 15, models 32 to 63. -+ * -+ * Ref. http://support.amd.com/TechDocs/25759.pdf errata #147. -+ */ -+ -+/* Barriers. */ -+ -+#define compiler_barrier() asm volatile(" " : : : "memory") -+#define cpu_barrier() asm volatile("lock; addl $0,(%%esp)" ::: "memory", "cc") -+ -+/* -+ * The 'volatile' keyword prevents the compiler from keeping the atomic -+ * value in a register, and generates a new memory access for each atomic -+ * operation. This allows the implementations of memory_order_relaxed and -+ * memory_order_consume to avoid issuing a compiler memory barrier, allowing -+ * full optimization of all surrounding non-atomic variables. -+ * -+ * The placement of the 'volatile' keyword after the 'TYPE' below is highly -+ * significant when the TYPE is a pointer type. In that case we want the -+ * pointer to be declared volatile, not the data type that is being pointed -+ * at! -+ * -+ * Attribute aligned is used to tell the compiler to align 64-bit data -+ * on a 8-byte boundary. This allows more efficient atomic access, as the -+ * the CPU guarantees such memory accesses to be atomic. */ -+#define ATOMIC(TYPE) TYPE volatile __attribute__((aligned(sizeof(TYPE)))) -+ -+/* Memory ordering. Must be passed in as a constant. */ -+typedef enum { -+ memory_order_relaxed, -+ memory_order_consume, -+ memory_order_acquire, -+ memory_order_release, -+ memory_order_acq_rel, -+ memory_order_seq_cst -+} memory_order; -+ -+#define ATOMIC_BOOL_LOCK_FREE 2 -+#define ATOMIC_CHAR_LOCK_FREE 2 -+#define ATOMIC_SHORT_LOCK_FREE 2 -+#define ATOMIC_INT_LOCK_FREE 2 -+#define ATOMIC_LONG_LOCK_FREE 2 -+#define ATOMIC_LLONG_LOCK_FREE 2 -+#define ATOMIC_POINTER_LOCK_FREE 2 -+ -+#define IS_LOCKLESS_ATOMIC(OBJECT) \ -+ (sizeof(OBJECT) <= 8 && IS_POW2(sizeof(OBJECT))) -+ -+#define ATOMIC_VAR_INIT(VALUE) VALUE -+#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -+ -+/* -+ * The memory_model_relaxed does not need a compiler barrier, if the -+ * atomic operation can otherwise be guaranteed to not be moved with -+ * respect to other atomic operations on the same memory location. Using -+ * the 'volatile' keyword in the definition of the atomic types -+ * accomplishes this, as memory accesses to volatile data may not be -+ * optimized away, or be reordered with other volatile accesses. -+ * -+ * On x86 also memory_order_consume is automatic, and data dependency on a -+ * volatile atomic variable means that the compiler optimizations should not -+ * cause problems. That is, the compiler should not speculate the value of -+ * the atomic_read, as it is going to read it from the memory anyway. -+ * This allows omiting the compiler memory barrier on atomic_reads with -+ * memory_order_consume. This matches the definition of -+ * smp_read_barrier_depends() in Linux kernel as a nop for x86, and its usage -+ * in rcu_dereference(). -+ * -+ * We use this same logic below to choose inline assembly statements with or -+ * without a compiler memory barrier. -+ */ -+static inline void -+atomic_compiler_barrier(memory_order order) -+{ -+ if (order > memory_order_consume) { -+ compiler_barrier(); -+ } -+} -+ -+static inline void -+atomic_thread_fence(memory_order order) -+{ -+ if (order == memory_order_seq_cst) { -+ cpu_barrier(); -+ } else { -+ atomic_compiler_barrier(order); -+ } -+} -+ -+static inline void -+atomic_signal_fence(memory_order order) -+{ -+ atomic_compiler_barrier(order); -+} -+ -+#define atomic_is_lock_free(OBJ) \ -+ ((void) *(OBJ), \ -+ IS_LOCKLESS_ATOMIC(*(OBJ)) ? 2 : 0) -+ -+/* The 8-byte atomic exchange uses cmpxchg8b with the SRC (ax:dx) as -+ * the expected value (bx:cx), which will get replaced by the current -+ * value in the likely case it did not match, after which we keep -+ * trying until the swap succeeds. */ -+ -+#if defined(__PIC__) -+/* ebx may not be clobbered when compiled with -fPIC, must save and -+ * restore it. Furthermore, 'DST' may be addressed via ebx, so the -+ * address must be passed via a register so that it remains valid also -+ * after changing ebx. */ -+#define atomic_exchange_8__(DST, SRC, CLOB) \ -+ uint32_t temp____; \ -+ \ -+ asm volatile(" movl %%ebx,%2 ; " \ -+ " movl %%eax,%%ebx ; " \ -+ " movl %%edx,%%ecx ; " \ -+ "1: " \ -+ "lock; cmpxchg8b (%0); " \ -+ " jne 1b ; " \ -+ " movl %2,%%ebx ; " \ -+ " # atomic_exchange_8__ " \ -+ : "+r" (DST), /* 0 */ \ -+ "+A" (SRC), /* 1 */ \ -+ "=mr" (temp____) /* 2 */ \ -+ :: "ecx", CLOB, "cc") -+ -+#else -+#define atomic_exchange_8__(DST, SRC, CLOB) \ -+ asm volatile(" movl %%eax,%%ebx ; " \ -+ " movl %%edx,%%ecx ; " \ -+ "1: " \ -+ "lock; cmpxchg8b %0 ; " \ -+ " jne 1b ; " \ -+ " # atomic_exchange_8__ " \ -+ : "+m" (*DST), /* 0 */ \ -+ "+A" (SRC) /* 1 */ \ -+ :: "ebx", "ecx", CLOB, "cc") -+#endif -+ -+#define atomic_exchange__(DST, SRC, ORDER) \ -+ ({ \ -+ typeof(DST) dst___ = (DST); \ -+ typeof(*(DST)) src___ = (SRC); \ -+ \ -+ if ((ORDER) > memory_order_consume) { \ -+ if (sizeof(*(DST)) == 8) { \ -+ atomic_exchange_8__(dst___, src___, "memory"); \ -+ } else { \ -+ asm volatile("xchg %1,%0 ; " \ -+ "# atomic_exchange__" \ -+ : "+r" (src___), /* 0 */ \ -+ "+m" (*dst___) /* 1 */ \ -+ :: "memory"); \ -+ } \ -+ } else { \ -+ if (sizeof(*(DST)) == 8) { \ -+ atomic_exchange_8__(dst___, src___, "cc"); \ -+ } else { \ -+ asm volatile("xchg %1,%0 ; " \ -+ "# atomic_exchange__" \ -+ : "+r" (src___), /* 0 */ \ -+ "+m" (*dst___)); /* 1 */ \ -+ } \ -+ } \ -+ src___; \ -+ }) -+ -+#if defined(__SSE__) -+/* SSE registers are 128-bit wide, and moving the lowest 64-bits of an SSE -+ * register to proerly aligned memory is atomic. See ATOMIC(TYPE) above. */ -+#define atomic_store_8__(DST, SRC) \ -+ asm volatile("movq %1,%0 ; # atomic_store_8__" \ -+ : "=m" (*DST) /* 0 */ \ -+ : "x" (SRC)) /* 1, SSE */ -+#else -+/* Locked 64-bit exchange is available on all i586 CPUs. */ -+#define atomic_store_8__(DST, SRC) \ -+ atomic_exchange_8__(DST, SRC, "cc") -+#endif -+ -+#define atomic_store_explicit(DST, SRC, ORDER) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(*(DST)) src__ = (SRC); \ -+ \ -+ if ((ORDER) != memory_order_seq_cst) { \ -+ atomic_compiler_barrier(ORDER); \ -+ if (sizeof(*(DST)) == 8) { \ -+ atomic_store_8__(dst__, src__); \ -+ } else { \ -+ *dst__ = src__; \ -+ } \ -+ } else { \ -+ atomic_exchange__(dst__, src__, ORDER); \ -+ } \ -+ (void) 0; \ -+ }) -+#define atomic_store(DST, SRC) \ -+ atomic_store_explicit(DST, SRC, memory_order_seq_cst) -+ -+#if defined(__SSE__) -+/* SSE registers are 128-bit wide, and moving 64-bits from properly aligned -+ * memory to an SSE register is atomic. See ATOMIC(TYPE) above. */ -+#define atomic_read_8__(SRC, DST) \ -+ ({ \ -+ typeof(*(DST)) res__; \ -+ \ -+ asm ("movq %1,%0 ; # atomic_read_8__" \ -+ : "=x" (res__) /* 0, SSE. */ \ -+ : "m" (*SRC)); /* 1 */ \ -+ *(DST) = res__; \ -+ }) -+#else -+/* Must use locked cmpxchg8b (available on all i586 CPUs) if compiled w/o sse -+ * support. Compare '*DST' to a random value in bx:cx and returns the actual -+ * value in ax:dx. The registers bx and cx are only read, so they are not -+ * clobbered. */ -+#define atomic_read_8__(SRC, DST) \ -+ ({ \ -+ typeof(*(DST)) res__; \ -+ \ -+ asm (" movl %%ebx,%%eax ; " \ -+ " movl %%ecx,%%edx ; " \ -+ "lock; cmpxchg8b %1 ; " \ -+ "# atomic_read_8__ " \ -+ : "=&A" (res__), /* 0 */ \ -+ "+m" (*SRC) /* 1 */ \ -+ : : "cc"); \ -+ *(DST) = res__; \ -+ }) -+#endif -+ -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(SRC) src__ = (SRC); \ -+ \ -+ if (sizeof(*(DST)) <= 4) { \ -+ *dst__ = *src__; \ -+ } else { \ -+ atomic_read_8__(SRC, DST); \ -+ } \ -+ atomic_compiler_barrier(ORDER); \ -+ (void) 0; \ -+ }) -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+ -+#if defined(__PIC__) -+/* ebx may not be used as an input when compiled with -fPIC, must save -+ * and restore it. Furthermore, 'DST' may be addressed via ebx, so -+ * the address must be passed via a register so that it remains valid -+ * also after changing ebx. */ -+#define atomic_compare_exchange_8__(DST, EXP, SRC, RES, CLOB) \ -+ asm volatile(" xchgl %%ebx,%3 ; " \ -+ "lock; cmpxchg8b (%1) ; " \ -+ " xchgl %3,%%ebx ; " \ -+ " sete %0 " \ -+ "# atomic_compare_exchange_8__" \ -+ : "=q" (RES), /* 0 */ \ -+ "+r" (DST), /* 1 */ \ -+ "+A" (EXP) /* 2 */ \ -+ : "r" ((uint32_t)SRC), /* 3 */ \ -+ "c" ((uint32_t)((uint64_t)SRC >> 32)) /* 4 */ \ -+ : CLOB, "cc") -+#else -+#define atomic_compare_exchange_8__(DST, EXP, SRC, RES, CLOB) \ -+ asm volatile("lock; cmpxchg8b %1 ; " \ -+ " sete %0 " \ -+ "# atomic_compare_exchange_8__" \ -+ : "=q" (RES), /* 0 */ \ -+ "+m" (*DST), /* 1 */ \ -+ "+A" (EXP) /* 2 */ \ -+ : "b" ((uint32_t)SRC), /* 3 */ \ -+ "c" ((uint32_t)((uint64_t)SRC >> 32)) /* 4 */ \ -+ : CLOB, "cc") -+#endif -+ -+#define atomic_compare_exchange__(DST, EXP, SRC, RES, CLOB) \ -+ asm volatile("lock; cmpxchg %3,%1 ; " \ -+ " sete %0 " \ -+ "# atomic_compare_exchange__" \ -+ : "=q" (RES), /* 0 */ \ -+ "+m" (*DST), /* 1 */ \ -+ "+a" (EXP) /* 2 */ \ -+ : "r" (SRC) /* 3 */ \ -+ : CLOB, "cc") -+ -+/* ORD_FAIL is ignored, as atomic_compare_exchange__ already implements -+ * at least as strong a barrier as allowed for ORD_FAIL in all cases. */ -+#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORDER, ORD_FAIL) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(DST) expp__ = (EXP); \ -+ typeof(*(DST)) src__ = (SRC); \ -+ typeof(*(DST)) exp__ = *expp__; \ -+ uint8_t res__; \ -+ (void)ORD_FAIL; \ -+ \ -+ if ((ORDER) > memory_order_consume) { \ -+ if (sizeof(*(DST)) <= 4) { \ -+ atomic_compare_exchange__(dst__, exp__, src__, res__, \ -+ "memory"); \ -+ } else { \ -+ atomic_compare_exchange_8__(dst__, exp__, src__, res__, \ -+ "memory"); \ -+ } \ -+ } else { \ -+ if (sizeof(*(DST)) <= 4) { \ -+ atomic_compare_exchange__(dst__, exp__, src__, res__, \ -+ "cc"); \ -+ } else { \ -+ atomic_compare_exchange_8__(dst__, exp__, src__, res__, \ -+ "cc"); \ -+ } \ -+ } \ -+ if (!res__) { \ -+ *expp__ = exp__; \ -+ } \ -+ (bool)res__; \ -+ }) -+#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -+ atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -+ memory_order_seq_cst, \ -+ memory_order_seq_cst) -+#define atomic_compare_exchange_weak \ -+ atomic_compare_exchange_strong -+#define atomic_compare_exchange_weak_explicit \ -+ atomic_compare_exchange_strong_explicit -+ -+#define atomic_exchange_explicit(RMW, ARG, ORDER) \ -+ atomic_exchange__(RMW, ARG, ORDER) -+#define atomic_exchange(RMW, ARG) \ -+ atomic_exchange_explicit(RMW, ARG, memory_order_seq_cst) -+ -+#define atomic_add__(RMW, ARG, CLOB) \ -+ asm volatile("lock; xadd %0,%1 ; " \ -+ "# atomic_add__ " \ -+ : "+r" (ARG), /* 0 */ \ -+ "+m" (*RMW) /* 1 */ \ -+ :: CLOB, "cc") -+ -+#define atomic_add_32__(RMW, ARG, ORIG, ORDER) \ -+ ({ \ -+ typeof(RMW) rmw__ = (RMW); \ -+ typeof(*(RMW)) arg__ = (ARG); \ -+ \ -+ if ((ORDER) > memory_order_consume) { \ -+ atomic_add__(rmw__, arg__, "memory"); \ -+ } else { \ -+ atomic_add__(rmw__, arg__, "cc"); \ -+ } \ -+ *(ORIG) = arg__; \ -+ }) -+ -+/* We could use simple locked instructions if the original value was not -+ * needed. */ -+#define atomic_op__(RMW, OP, ARG, ORIG, ORDER) \ -+ ({ \ -+ typeof(RMW) rmw__ = (RMW); \ -+ typeof(ARG) arg__ = (ARG); \ -+ \ -+ typeof(*(RMW)) val__; \ -+ \ -+ atomic_read_explicit(rmw__, &val__, memory_order_relaxed); \ -+ do { \ -+ } while (!atomic_compare_exchange_weak_explicit(rmw__, &val__, \ -+ val__ OP arg__, \ -+ ORDER, \ -+ memory_order_relaxed)); \ -+ *(ORIG) = val__; \ -+ }) -+ -+#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -+ (sizeof(*(RMW)) <= 4 \ -+ ? atomic_add_32__(RMW, ARG, ORIG, ORDER) \ -+ : atomic_op__(RMW, +, ARG, ORIG, ORDER)) -+#define atomic_add(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -+ (sizeof(*(RMW)) <= 4 \ -+ ? atomic_add_32__(RMW, -(ARG), ORIG, ORDER) \ -+ : atomic_op__(RMW, -, ARG, ORIG, ORDER)) -+#define atomic_sub(RMW, ARG, ORIG) \ -+ atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_op__(RMW, |, ARG, ORIG, ORDER) -+#define atomic_or(RMW, ARG, ORIG) \ -+ atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_op__(RMW, ^, ARG, ORIG, ORDER) -+#define atomic_xor(RMW, ARG, ORIG) \ -+ atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_op__(RMW, &, ARG, ORIG, ORDER) -+#define atomic_and(RMW, ARG, ORIG) \ -+ atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+ -+/* atomic_flag */ -+ -+typedef ATOMIC(int) atomic_flag; -+#define ATOMIC_FLAG_INIT { false } -+ -+#define atomic_flag_test_and_set_explicit(FLAG, ORDER) \ -+ ((bool)atomic_exchange__(FLAG, 1, ORDER)) -+#define atomic_flag_test_and_set(FLAG) \ -+ atomic_flag_test_and_set_explicit(FLAG, memory_order_seq_cst) -+ -+#define atomic_flag_clear_explicit(FLAG, ORDER) \ -+ atomic_store_explicit(FLAG, 0, ORDER) -+#define atomic_flag_clear(FLAG) \ -+ atomic_flag_clear_explicit(FLAG, memory_order_seq_cst) -Index: openvswitch-2.17.2/include/internal/ovs-atomic-locked.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-locked.h -@@ -0,0 +1,52 @@ -+/* This header implements atomic operation locking helpers. */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#define OVS_ATOMIC_LOCKED_IMPL 1 -+ -+void atomic_lock__(void *); -+void atomic_unlock__(void *); -+ -+#define atomic_store_locked(DST, SRC) \ -+ (atomic_lock__(DST), \ -+ *(DST) = (SRC), \ -+ atomic_unlock__(DST), \ -+ (void) 0) -+ -+#define atomic_read_locked(SRC, DST) \ -+ (atomic_lock__(SRC), \ -+ *(DST) = *(SRC), \ -+ atomic_unlock__(SRC), \ -+ (void) 0) -+ -+/* XXX: Evaluates EXP multiple times. */ -+#define atomic_compare_exchange_locked(DST, EXP, SRC) \ -+ (atomic_lock__(DST), \ -+ (*(DST) == *(EXP) \ -+ ? (*(DST) = (SRC), \ -+ atomic_unlock__(DST), \ -+ true) \ -+ : (*(EXP) = *(DST), \ -+ atomic_unlock__(DST), \ -+ false))) -+ -+#define atomic_exchange_locked(DST, SRC) \ -+ ({ \ -+ atomic_lock__(DST); \ -+ typeof(*(DST)) __tmp = *(DST); \ -+ *(DST) = SRC; \ -+ atomic_unlock__(DST); \ -+ __tmp; \ -+ }) -+ -+#define atomic_op_locked_add += -+#define atomic_op_locked_sub -= -+#define atomic_op_locked_or |= -+#define atomic_op_locked_xor ^= -+#define atomic_op_locked_and &= -+#define atomic_op_locked(RMW, OP, OPERAND, ORIG) \ -+ (atomic_lock__(RMW), \ -+ *(ORIG) = *(RMW), \ -+ *(RMW) atomic_op_locked_##OP (OPERAND), \ -+ atomic_unlock__(RMW)) -Index: openvswitch-2.17.2/include/internal/ovs-atomic-msvc.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-msvc.h -@@ -0,0 +1,463 @@ -+/* -+ * Copyright (c) 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives for MSVC -+ * on i586 or greater platforms (32 bit). */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+/* From msdn documentation: With Visual Studio 2003, volatile to volatile -+ * references are ordered; the compiler will not re-order volatile variable -+ * access. With Visual Studio 2005, the compiler also uses acquire semantics -+ * for read operations on volatile variables and release semantics for write -+ * operations on volatile variables (when supported by the CPU). -+ * -+ * Though there is no clear documentation that states that anything greater -+ * than VS 2005 has the same behavior as described above, looking through MSVCs -+ * C++ atomics library in VS2013 shows that the compiler still takes -+ * acquire/release semantics on volatile variables. */ -+#define ATOMIC(TYPE) TYPE volatile -+ -+typedef enum { -+ memory_order_relaxed, -+ memory_order_consume, -+ memory_order_acquire, -+ memory_order_release, -+ memory_order_acq_rel, -+ memory_order_seq_cst -+} memory_order; -+ -+#if _MSC_VER > 1800 && defined(_M_IX86) -+/* From WDK 10 _InlineInterlocked* functions are renamed to -+ * _InlineInterlocked* although the documentation does not specify it */ -+#define _InterlockedExchangeAdd64 _InlineInterlockedExchangeAdd64 -+#define _InterlockedExchange64 _InlineInterlockedExchange64 -+#endif -+ -+#define ATOMIC_BOOL_LOCK_FREE 2 -+#define ATOMIC_CHAR_LOCK_FREE 2 -+#define ATOMIC_SHORT_LOCK_FREE 2 -+#define ATOMIC_INT_LOCK_FREE 2 -+#define ATOMIC_LONG_LOCK_FREE 2 -+#define ATOMIC_LLONG_LOCK_FREE 2 -+#define ATOMIC_POINTER_LOCK_FREE 2 -+ -+#define IS_LOCKLESS_ATOMIC(OBJECT) \ -+ (sizeof(OBJECT) <= 8 && IS_POW2(sizeof(OBJECT))) -+ -+#define ATOMIC_VAR_INIT(VALUE) (VALUE) -+#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -+ -+static inline void -+atomic_compiler_barrier(memory_order order) -+{ -+ /* In case of 'memory_order_consume', it is implicitly assumed that -+ * the compiler will not move instructions that have data-dependency -+ * on the variable in question before the barrier. */ -+ if (order > memory_order_consume) { -+ _ReadWriteBarrier(); -+ } -+} -+ -+static inline void -+atomic_thread_fence(memory_order order) -+{ -+ /* x86 is strongly ordered and acquire/release semantics come -+ * automatically. */ -+ atomic_compiler_barrier(order); -+ if (order == memory_order_seq_cst) { -+ MemoryBarrier(); -+ atomic_compiler_barrier(order); -+ } -+} -+ -+static inline void -+atomic_signal_fence(memory_order order) -+{ -+ atomic_compiler_barrier(order); -+} -+ -+/* 1, 2 and 4 bytes loads and stores are atomic on aligned memory. In addition, -+ * since the compiler automatically takes acquire and release semantics on -+ * volatile variables, for any order lesser than 'memory_order_seq_cst', we -+ * can directly assign or read values. */ -+ -+#define atomic_store32(DST, SRC, ORDER) \ -+ if (ORDER == memory_order_seq_cst) { \ -+ InterlockedExchange((long volatile *) (DST), \ -+ (long) (SRC)); \ -+ } else { \ -+ *(DST) = (SRC); \ -+ } -+ -+/* MSVC converts 64 bit writes into two instructions. So there is -+ * a possibility that an interrupt can make a 64 bit write non-atomic even -+ * when 8 byte aligned. So use InterlockedExchange64(). -+ * -+ * For atomic stores, 'consume' and 'acquire' semantics are not valid. But we -+ * are using 'Exchange' to get atomic stores here and we only have -+ * InterlockedExchange64(), InterlockedExchangeNoFence64() and -+ * InterlockedExchange64Acquire() available. So we are forced to use -+ * InterlockedExchange64() which uses full memory barrier for everything -+ * greater than 'memory_order_relaxed'. */ -+#ifdef _M_IX86 -+#define atomic_store64(DST, SRC, ORDER) \ -+ if (ORDER == memory_order_relaxed) { \ -+ InterlockedExchangeNoFence64((int64_t volatile *) (DST), \ -+ (int64_t) (SRC)); \ -+ } else { \ -+ InterlockedExchange64((int64_t volatile *) (DST), (int64_t) (SRC));\ -+ } -+#elif _M_X64 -+/* 64 bit writes are atomic on amd64 if 64 bit aligned. */ -+#define atomic_store64(DST, SRC, ORDER) \ -+ if (ORDER == memory_order_seq_cst) { \ -+ InterlockedExchange64((int64_t volatile *) (DST), \ -+ (int64_t) (SRC)); \ -+ } else { \ -+ *(DST) = (SRC); \ -+ } -+#endif -+ -+#define atomic_store8(DST, SRC, ORDER) \ -+ if (ORDER == memory_order_seq_cst) { \ -+ InterlockedExchange8((char volatile *) (DST), (char) (SRC)); \ -+ } else { \ -+ *(DST) = (SRC); \ -+ } -+ -+#define atomic_store16(DST, SRC, ORDER) \ -+ if (ORDER == memory_order_seq_cst) { \ -+ InterlockedExchange16((short volatile *) (DST), (short) (SRC)); \ -+ } else { \ -+ *(DST) = (SRC); \ -+ } -+ -+#define atomic_store(DST, SRC) \ -+ atomic_store_explicit(DST, SRC, memory_order_seq_cst) -+ -+#define atomic_store_explicit(DST, SRC, ORDER) \ -+ if (sizeof *(DST) == 1) { \ -+ atomic_store8(DST, SRC, ORDER) \ -+ } else if (sizeof *(DST) == 2) { \ -+ atomic_store16( DST, SRC, ORDER) \ -+ } else if (sizeof *(DST) == 4) { \ -+ atomic_store32(DST, SRC, ORDER) \ -+ } else if (sizeof *(DST) == 8) { \ -+ atomic_store64(DST, SRC, ORDER) \ -+ } else { \ -+ abort(); \ -+ } -+ -+/* On x86, for 'memory_order_seq_cst', if stores are locked, the corresponding -+ * reads don't need to be locked (based on the following in Intel Developers -+ * manual: -+ * “Locked operations are atomic with respect to all other memory operations -+ * and all externally visible events. Only instruction fetch and page table -+ * accesses can pass locked instructions. Locked instructions can be used to -+ * synchronize data written by one processor and read by another processor. -+ * For the P6 family processors, locked operations serialize all outstanding -+ * load and store operations (that is, wait for them to complete). This rule -+ * is also true for the Pentium 4 and Intel Xeon processors, with one -+ * exception. Load operations that reference weakly ordered memory types -+ * (such as the WC memory type) may not be serialized."). */ -+ -+ /* For 8, 16 and 32 bit variations. */ -+#define atomic_readX(SRC, DST, ORDER) \ -+ *(DST) = *(SRC); -+ -+/* MSVC converts 64 bit reads into two instructions. So there is -+ * a possibility that an interrupt can make a 64 bit read non-atomic even -+ * when 8 byte aligned. So use fully memory barrier InterlockedOr64(). */ -+#ifdef _M_IX86 -+#define atomic_read64(SRC, DST, ORDER) \ -+ __pragma (warning(push)) \ -+ __pragma (warning(disable:4047)) \ -+ *(DST) = InterlockedOr64((int64_t volatile *) (SRC), 0); \ -+ __pragma (warning(pop)) -+#elif _M_X64 -+/* 64 bit reads are atomic on amd64 if 64 bit aligned. */ -+#define atomic_read64(SRC, DST, ORDER) \ -+ *(DST) = *(SRC); -+#endif -+ -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+ -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ if (sizeof *(DST) == 1 || sizeof *(DST) == 2 || sizeof *(DST) == 4) { \ -+ atomic_readX(SRC, DST, ORDER) \ -+ } else if (sizeof *(DST) == 8) { \ -+ atomic_read64(SRC, DST, ORDER) \ -+ } else { \ -+ abort(); \ -+ } -+ -+/* For add, sub, and logical operations, for 8, 16 and 64 bit data types, -+ * functions for all the different memory orders does not exist -+ * (though documentation exists for some of them). The MSVC C++ library which -+ * implements the c11 atomics simply calls the full memory barrier function -+ * for everything in x86(see xatomic.h). So do the same here. */ -+ -+/* For 8, 16 and 64 bit variations. */ -+#define atomic_op(OP, X, RMW, ARG, ORIG, ORDER) \ -+ atomic_##OP##_generic(X, RMW, ARG, ORIG, ORDER) -+ -+/* Arithmetic addition calls. */ -+ -+#define atomic_add8(RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = _InterlockedExchangeAdd8((char volatile *) (RMW), \ -+ (char) (ARG)); -+ -+#define atomic_add16(RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = _InterlockedExchangeAdd16((short volatile *) (RMW), \ -+ (short) (ARG)); -+ -+#define atomic_add32(RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = InterlockedExchangeAdd((long volatile *) (RMW), \ -+ (long) (ARG)); -+#define atomic_add64(RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = _InterlockedExchangeAdd64((int64_t volatile *) (RMW), \ -+ (int64_t) (ARG)); -+ -+#define atomic_add(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -+ if (sizeof *(RMW) == 1) { \ -+ atomic_add8(RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 2) { \ -+ atomic_add16(RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 4) { \ -+ atomic_add32(RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 8) { \ -+ atomic_add64(RMW, ARG, ORIG, ORDER) \ -+ } else { \ -+ abort(); \ -+ } -+ -+/* Arithmetic subtraction calls. */ -+ -+#define atomic_sub(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, (0 - (ARG)), ORIG, memory_order_seq_cst) -+ -+#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_add_explicit(RMW, (0 - (ARG)), ORIG, ORDER) -+ -+/* Logical 'and' calls. */ -+ -+#define atomic_and32(RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = InterlockedAnd((int32_t volatile *) (RMW), (int32_t) (ARG)); -+ -+/* For 8, 16 and 64 bit variations. */ -+#define atomic_and_generic(X, RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = InterlockedAnd##X((int##X##_t volatile *) (RMW), \ -+ (int##X##_t) (ARG)); -+ -+#define atomic_and(RMW, ARG, ORIG) \ -+ atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -+ if (sizeof *(RMW) == 1) { \ -+ atomic_op(and, 8, RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 2) { \ -+ atomic_op(and, 16, RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 4) { \ -+ atomic_and32(RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 8) { \ -+ atomic_op(and, 64, RMW, ARG, ORIG, ORDER) \ -+ } else { \ -+ abort(); \ -+ } -+ -+/* Logical 'Or' calls. */ -+ -+#define atomic_or32(RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = InterlockedOr((int32_t volatile *) (RMW), (int32_t) (ARG)); -+ -+/* For 8, 16 and 64 bit variations. */ -+#define atomic_or_generic(X, RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = InterlockedOr##X((int##X##_t volatile *) (RMW), \ -+ (int##X##_t) (ARG)); -+ -+#define atomic_or(RMW, ARG, ORIG) \ -+ atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -+ if (sizeof *(RMW) == 1) { \ -+ atomic_op(or, 8, RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 2) { \ -+ atomic_op(or, 16, RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 4) { \ -+ atomic_or32(RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 8) { \ -+ atomic_op(or, 64, RMW, ARG, ORIG, ORDER) \ -+ } else { \ -+ abort(); \ -+ } -+ -+/* Logical Xor calls. */ -+ -+#define atomic_xor32(RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = InterlockedXor((int32_t volatile *) (RMW), (int32_t) (ARG)); -+ -+/* For 8, 16 and 64 bit variations. */ -+#define atomic_xor_generic(X, RMW, ARG, ORIG, ORDER) \ -+ *(ORIG) = InterlockedXor##X((int##X##_t volatile *) (RMW), \ -+ (int##X##_t) (ARG)); -+ -+#define atomic_xor(RMW, ARG, ORIG) \ -+ atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -+ if (sizeof *(RMW) == 1) { \ -+ atomic_op(xor, 8, RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 2) { \ -+ atomic_op(xor, 16, RMW, ARG, ORIG, ORDER) \ -+ } else if (sizeof *(RMW) == 4) { \ -+ atomic_xor32(RMW, ARG, ORIG, ORDER); \ -+ } else if (sizeof *(RMW) == 8) { \ -+ atomic_op(xor, 64, RMW, ARG, ORIG, ORDER) \ -+ } else { \ -+ abort(); \ -+ } -+ -+#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -+ atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -+ memory_order_seq_cst, \ -+ memory_order_seq_cst) -+ -+#define atomic_compare_exchange_weak atomic_compare_exchange_strong -+#define atomic_compare_exchange_weak_explicit \ -+ atomic_compare_exchange_strong_explicit -+ -+/* While intrinsics offering different memory ordering -+ * are available in MSVC C compiler, they are not defined -+ * in the C++ compiler. Ignore for compatibility. -+ * -+ * Use nested ternary operators as the GNU extension ({}) -+ * is not available. -+ */ -+ -+#define atomic_exchange_explicit(DST, SRC, ORDER) \ -+ ((sizeof *(DST) == 1) ? \ -+ _InterlockedExchange8((char volatile *) DST, SRC) \ -+ : (sizeof *(DST) == 2) ? \ -+ _InterlockedExchange16((short volatile *) DST, SRC) \ -+ : (sizeof *(DST) == 4) ? \ -+ _InterlockedExchange((long int volatile *) DST, SRC) \ -+ : (sizeof *(DST) == 8) ? \ -+ _InterlockedExchange64((__int64 volatile *) DST, SRC) \ -+ : (abort(), 0)) -+ -+#define atomic_exchange(DST, SRC) \ -+ atomic_exchange_explicit(DST, SRC, memory_order_seq_cst) -+ -+/* MSVCs c++ compiler implements c11 atomics and looking through its -+ * implementation (in xatomic.h), orders are ignored for x86 platform. -+ * Do the same here. */ -+static inline bool -+atomic_compare_exchange8(int8_t volatile *dst, int8_t *expected, int8_t src) -+{ -+ int8_t previous = _InterlockedCompareExchange8((char volatile *)dst, -+ src, *expected); -+ if (previous == *expected) { -+ return true; -+ } else { -+ *expected = previous; -+ return false; -+ } -+} -+ -+static inline bool -+atomic_compare_exchange16(int16_t volatile *dst, int16_t *expected, -+ int16_t src) -+{ -+ int16_t previous = InterlockedCompareExchange16(dst, src, *expected); -+ if (previous == *expected) { -+ return true; -+ } else { -+ *expected = previous; -+ return false; -+ } -+} -+ -+static inline bool -+atomic_compare_exchange32(int32_t volatile *dst, int32_t *expected, -+ int32_t src) -+{ -+ int32_t previous = InterlockedCompareExchange((long volatile *)dst, -+ src, *expected); -+ if (previous == *expected) { -+ return true; -+ } else { -+ *expected = previous; -+ return false; -+ } -+} -+ -+static inline bool -+atomic_compare_exchange64(int64_t volatile *dst, int64_t *expected, -+ int64_t src) -+{ -+ int64_t previous = InterlockedCompareExchange64(dst, src, *expected); -+ if (previous == *expected) { -+ return true; -+ } else { -+ *expected = previous; -+ return false; -+ } -+} -+ -+static inline bool -+atomic_compare_unreachable() -+{ -+ return true; -+} -+ -+#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -+ (sizeof *(DST) == 1 \ -+ ? atomic_compare_exchange8((int8_t volatile *) (DST), (int8_t *) (EXP), \ -+ (int8_t) (SRC)) \ -+ : (sizeof *(DST) == 2 \ -+ ? atomic_compare_exchange16((int16_t volatile *) (DST), \ -+ (int16_t *) (EXP), (int16_t) (SRC)) \ -+ : (sizeof *(DST) == 4 \ -+ ? atomic_compare_exchange32((int32_t volatile *) (DST), \ -+ (int32_t *) (EXP), (int32_t) (SRC)) \ -+ : (sizeof *(DST) == 8 \ -+ ? atomic_compare_exchange64((int64_t volatile *) (DST), \ -+ (int64_t *) (EXP), (int64_t) (SRC)) \ -+ : ovs_fatal(0, "atomic operation with size greater than 8 bytes"), \ -+ atomic_compare_unreachable())))) -+ -+ -+/* atomic_flag */ -+ -+typedef ATOMIC(int32_t) atomic_flag; -+#define ATOMIC_FLAG_INIT 0 -+ -+#define atomic_flag_test_and_set(FLAG) \ -+ (bool) InterlockedBitTestAndSet(FLAG, 0) -+ -+#define atomic_flag_test_and_set_explicit(FLAG, ORDER) \ -+ atomic_flag_test_and_set(FLAG) -+ -+#define atomic_flag_clear_explicit(FLAG, ORDER) \ -+ atomic_flag_clear() -+#define atomic_flag_clear(FLAG) \ -+ InterlockedBitTestAndReset(FLAG, 0) -Index: openvswitch-2.17.2/include/internal/ovs-atomic-x86_64.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/ovs-atomic-x86_64.h -@@ -0,0 +1,356 @@ -+/* -+ * Copyright (c) 2014 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* This header implements atomic operation primitives on x86_64 with GCC. */ -+#ifndef IN_OVS_ATOMIC_H -+#error "This header should only be included indirectly via ovs-atomic.h." -+#endif -+ -+#define OVS_ATOMIC_X86_64_IMPL 1 -+ -+/* -+ * x86_64 Memory model (http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html): -+ * -+ * - 1, 2, 4, and 8 byte loads and stores are atomic on aligned memory. -+ * - Loads are not reordered with other loads. -+ * - Stores are not reordered with OLDER loads. -+ * - Loads may be reordered with OLDER stores to a different memory location, -+ * but not with OLDER stores to the same memory location. -+ * - Stores are not reordered with other stores, except for special -+ * instructions (CLFLUSH, streaming stores, fast string operations). -+ * Most of these are not emitted by compilers, and as long as the -+ * atomic stores are not combined with any other stores, even the allowed -+ * reordering of the stores by a single fast string operation (e.g., "stos") -+ * is not a problem. -+ * - Neither loads nor stores are reordered with locked instructions. -+ * - Loads cannot pass earlier LFENCE or MFENCE instructions. -+ * - Stores cannot pass earlier LFENCE, SFENCE, or MFENCE instructions. -+ * - LFENCE instruction cannot pass earlier loads. -+ * - SFENCE instruction cannot pass earlier stores. -+ * - MFENCE instruction cannot pass earlier loads or stores. -+ * - Stores by a single processor are observed in the same order by all -+ * processors. -+ * - (Unlocked) Stores from different processors are NOT ordered. -+ * - Memory ordering obeys causality (memory ordering respects transitive -+ * visibility). -+ * - Any two stores are seen in a consistent order by processors other than -+ * the those performing the stores. -+ * - Locked instructions have total order. -+ * -+ * These rules imply that: -+ * -+ * - Locked instructions are not needed for aligned loads or stores to make -+ * them atomic. -+ * - All stores have release semantics; none of the preceding stores or loads -+ * can be reordered with following stores. Following loads could still be -+ * reordered to happen before the store, but that is not a violation of the -+ * release semantics. -+ * - All loads from a given memory location have acquire semantics with -+ * respect to the stores on the same memory location; none of the following -+ * loads or stores can be reordered with the load. Preceding stores to a -+ * different memory location MAY be reordered with the load, but that is not -+ * a violation of the acquire semantics (i.e., the loads and stores of two -+ * critical sections guarded by a different memory location can overlap). -+ * - Locked instructions serve as CPU memory barriers by themselves. -+ * - Locked stores implement the sequential consistency memory order. Using -+ * locked instructions when seq_cst memory order is requested allows normal -+ * loads to observe the stores in the same (total) order without using CPU -+ * memory barrier after the loads. -+ * -+ * NOTE: Some older AMD Opteron processors have a bug that violates the -+ * acquire semantics described above. The bug manifests as an unlocked -+ * read-modify-write operation following a "semaphore operation" operating -+ * on data that existed before entering the critical section; i.e., the -+ * preceding "semaphore operation" fails to function as an acquire barrier. -+ * The affected CPUs are AMD family 15, models 32 to 63. -+ * -+ * Ref. http://support.amd.com/TechDocs/25759.pdf errata #147. -+ */ -+ -+/* Barriers. */ -+ -+#define compiler_barrier() asm volatile(" " : : : "memory") -+#define cpu_barrier() asm volatile("mfence;" : : : "memory") -+ -+/* -+ * The 'volatile' keyword prevents the compiler from keeping the atomic -+ * value in a register, and generates a new memory access for each atomic -+ * operation. This allows the implementations of memory_order_relaxed and -+ * memory_order_consume to avoid issuing a compiler memory barrier, allowing -+ * full optimization of all surrounding non-atomic variables. -+ * -+ * The placement of the 'volatile' keyword after the 'TYPE' below is highly -+ * significant when the TYPE is a pointer type. In that case we want the -+ * pointer to be declared volatile, not the data type that is being pointed -+ * at! -+ */ -+#define ATOMIC(TYPE) TYPE volatile -+ -+/* Memory ordering. Must be passed in as a constant. */ -+typedef enum { -+ memory_order_relaxed, -+ memory_order_consume, -+ memory_order_acquire, -+ memory_order_release, -+ memory_order_acq_rel, -+ memory_order_seq_cst -+} memory_order; -+ -+#define ATOMIC_BOOL_LOCK_FREE 2 -+#define ATOMIC_CHAR_LOCK_FREE 2 -+#define ATOMIC_SHORT_LOCK_FREE 2 -+#define ATOMIC_INT_LOCK_FREE 2 -+#define ATOMIC_LONG_LOCK_FREE 2 -+#define ATOMIC_LLONG_LOCK_FREE 2 -+#define ATOMIC_POINTER_LOCK_FREE 2 -+ -+#define IS_LOCKLESS_ATOMIC(OBJECT) \ -+ (sizeof(OBJECT) <= 8 && IS_POW2(sizeof(OBJECT))) -+ -+#define ATOMIC_VAR_INIT(VALUE) VALUE -+#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -+ -+/* -+ * The memory_model_relaxed does not need a compiler barrier, if the -+ * atomic operation can otherwise be guaranteed to not be moved with -+ * respect to other atomic operations on the same memory location. Using -+ * the 'volatile' keyword in the definition of the atomic types -+ * accomplishes this, as memory accesses to volatile data may not be -+ * optimized away, or be reordered with other volatile accesses. -+ * -+ * On x86 also memory_order_consume is automatic, and data dependency on a -+ * volatile atomic variable means that the compiler optimizations should not -+ * cause problems. That is, the compiler should not speculate the value of -+ * the atomic_read, as it is going to read it from the memory anyway. -+ * This allows omiting the compiler memory barrier on atomic_reads with -+ * memory_order_consume. This matches the definition of -+ * smp_read_barrier_depends() in Linux kernel as a nop for x86, and its usage -+ * in rcu_dereference(). -+ * -+ * We use this same logic below to choose inline assembly statements with or -+ * without a compiler memory barrier. -+ */ -+static inline void -+atomic_compiler_barrier(memory_order order) -+{ -+ if (order > memory_order_consume) { -+ compiler_barrier(); -+ } -+} -+ -+static inline void -+atomic_thread_fence(memory_order order) -+{ -+ if (order == memory_order_seq_cst) { -+ cpu_barrier(); -+ } else { -+ atomic_compiler_barrier(order); -+ } -+} -+ -+static inline void -+atomic_signal_fence(memory_order order) -+{ -+ atomic_compiler_barrier(order); -+} -+ -+#define atomic_is_lock_free(OBJ) \ -+ ((void) *(OBJ), \ -+ IS_LOCKLESS_ATOMIC(*(OBJ)) ? 2 : 0) -+ -+#define atomic_exchange__(DST, SRC, ORDER) \ -+ ({ \ -+ typeof(DST) dst___ = (DST); \ -+ typeof(*(DST)) src___ = (SRC); \ -+ \ -+ if ((ORDER) > memory_order_consume) { \ -+ asm volatile("xchg %1,%0 ; " \ -+ "# atomic_exchange__" \ -+ : "+r" (src___), /* 0 */ \ -+ "+m" (*dst___) /* 1 */ \ -+ :: "memory"); \ -+ } else { \ -+ asm volatile("xchg %1,%0 ; " \ -+ "# atomic_exchange__" \ -+ : "+r" (src___), /* 0 */ \ -+ "+m" (*dst___)); /* 1 */ \ -+ } \ -+ src___; \ -+ }) -+ -+/* Atomic store: Valid memory models are: -+ * -+ * memory_order_relaxed, memory_order_release, and -+ * memory_order_seq_cst. */ -+#define atomic_store_explicit(DST, SRC, ORDER) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(*(DST)) src__ = (SRC); \ -+ \ -+ if ((ORDER) != memory_order_seq_cst) { \ -+ atomic_compiler_barrier(ORDER); \ -+ *dst__ = src__; \ -+ } else { \ -+ atomic_exchange__(dst__, src__, ORDER); \ -+ } \ -+ (void) 0; \ -+ }) -+#define atomic_store(DST, SRC) \ -+ atomic_store_explicit(DST, SRC, memory_order_seq_cst) -+ -+/* Atomic read: Valid memory models are: -+ * -+ * memory_order_relaxed, memory_order_consume, memory_model_acquire, -+ * and memory_order_seq_cst. */ -+#define atomic_read_explicit(SRC, DST, ORDER) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(SRC) src__ = (SRC); \ -+ \ -+ *dst__ = *src__; \ -+ atomic_compiler_barrier(ORDER); \ -+ (void) 0; \ -+ }) -+#define atomic_read(SRC, DST) \ -+ atomic_read_explicit(SRC, DST, memory_order_seq_cst) -+ -+#define atomic_compare_exchange__(DST, EXP, SRC, RES, CLOB) \ -+ asm volatile("lock; cmpxchg %3,%1 ; " \ -+ " sete %0 " \ -+ "# atomic_compare_exchange__" \ -+ : "=q" (RES), /* 0 */ \ -+ "+m" (*DST), /* 1 */ \ -+ "+a" (EXP) /* 2 */ \ -+ : "r" (SRC) /* 3 */ \ -+ : CLOB, "cc") -+ -+/* All memory models are valid for read-modify-write operations. -+ * -+ * Valid memory models for the read operation of the current value in -+ * the failure case are the same as for atomic read, but can not be -+ * stronger than the success memory model. -+ * ORD_FAIL is ignored, as atomic_compare_exchange__ already implements -+ * at least as strong a barrier as allowed for ORD_FAIL in all cases. */ -+#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORDER, ORD_FAIL) \ -+ ({ \ -+ typeof(DST) dst__ = (DST); \ -+ typeof(DST) expp__ = (EXP); \ -+ typeof(*(DST)) src__ = (SRC); \ -+ typeof(*(DST)) exp__ = *expp__; \ -+ uint8_t res__; \ -+ (void)ORD_FAIL; \ -+ \ -+ if ((ORDER) > memory_order_consume) { \ -+ atomic_compare_exchange__(dst__, exp__, src__, res__, \ -+ "memory"); \ -+ } else { \ -+ atomic_compare_exchange__(dst__, exp__, src__, res__, \ -+ "cc"); \ -+ } \ -+ if (!res__) { \ -+ *expp__ = exp__; \ -+ } \ -+ (bool)res__; \ -+ }) -+#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -+ atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -+ memory_order_seq_cst, \ -+ memory_order_seq_cst) -+#define atomic_compare_exchange_weak \ -+ atomic_compare_exchange_strong -+#define atomic_compare_exchange_weak_explicit \ -+ atomic_compare_exchange_strong_explicit -+ -+#define atomic_exchange_explicit(RMW, ARG, ORDER) \ -+ atomic_exchange__(RMW, ARG, ORDER) -+#define atomic_exchange(RMW, ARG) \ -+ atomic_exchange_explicit(RMW, ARG, memory_order_seq_cst) -+ -+#define atomic_add__(RMW, ARG, CLOB) \ -+ asm volatile("lock; xadd %0,%1 ; " \ -+ "# atomic_add__ " \ -+ : "+r" (ARG), /* 0 */ \ -+ "+m" (*RMW) /* 1 */ \ -+ :: CLOB, "cc") -+ -+#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -+ ({ \ -+ typeof(RMW) rmw__ = (RMW); \ -+ typeof(*(RMW)) arg__ = (ARG); \ -+ \ -+ if ((ORDER) > memory_order_consume) { \ -+ atomic_add__(rmw__, arg__, "memory"); \ -+ } else { \ -+ atomic_add__(rmw__, arg__, "cc"); \ -+ } \ -+ *(ORIG) = arg__; \ -+ }) -+#define atomic_add(RMW, ARG, ORIG) \ -+ atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_add_explicit(RMW, -(ARG), ORIG, ORDER) -+#define atomic_sub(RMW, ARG, ORIG) \ -+ atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+/* We could use simple locked instructions if the original value was not -+ * needed. */ -+#define atomic_op__(RMW, OP, ARG, ORIG, ORDER) \ -+ ({ \ -+ typeof(RMW) rmw__ = (RMW); \ -+ typeof(ARG) arg__ = (ARG); \ -+ \ -+ typeof(*(RMW)) val__; \ -+ \ -+ atomic_read_explicit(rmw__, &val__, memory_order_relaxed); \ -+ do { \ -+ } while (!atomic_compare_exchange_weak_explicit(rmw__, &val__, \ -+ val__ OP arg__, \ -+ ORDER, \ -+ memory_order_relaxed)); \ -+ *(ORIG) = val__; \ -+ }) -+ -+#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_op__(RMW, |, ARG, ORIG, ORDER) -+#define atomic_or(RMW, ARG, ORIG) \ -+ atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_op__(RMW, ^, ARG, ORIG, ORDER) -+#define atomic_xor(RMW, ARG, ORIG) \ -+ atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -+ atomic_op__(RMW, &, ARG, ORIG, ORDER) -+#define atomic_and(RMW, ARG, ORIG) \ -+ atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -+ -+ -+/* atomic_flag */ -+ -+typedef ATOMIC(int) atomic_flag; -+#define ATOMIC_FLAG_INIT { false } -+ -+#define atomic_flag_test_and_set_explicit(FLAG, ORDER) \ -+ ((bool)atomic_exchange__(FLAG, 1, ORDER)) -+#define atomic_flag_test_and_set(FLAG) \ -+ atomic_flag_test_and_set_explicit(FLAG, memory_order_seq_cst) -+ -+#define atomic_flag_clear_explicit(FLAG, ORDER) \ -+ atomic_store_explicit(FLAG, 0, ORDER) -+#define atomic_flag_clear(FLAG) \ -+ atomic_flag_clear_explicit(FLAG, memory_order_seq_cst) -Index: openvswitch-2.17.2/include/internal/process.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/process.h -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (c) 2008, 2009, 2011, 2013 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef PROCESS_H -+#define PROCESS_H 1 -+ -+#include -+#include -+ -+struct process; -+ -+struct process_info { -+ unsigned long int vsz; /* Virtual size, in kB. */ -+ unsigned long int rss; /* Resident set size, in kB. */ -+ long long int booted; /* ms since monitor started. */ -+ int crashes; /* # of crashes (usually 0). */ -+ long long int uptime; /* ms since last (re)started by monitor. */ -+ long long int cputime; /* ms of CPU used during 'uptime'. */ -+ int core_id; -+ char name[18]; -+}; -+ -+/* Starting and monitoring subprocesses. -+ * -+ * process_init() and process_start() may safely be called only from a -+ * single-threaded parent process. The parent process may safely create -+ * additional threads afterward, as long as the remaining functions in this -+ * group are called only from a single thread at any given time. */ -+void process_init(void); -+int process_start(char **argv, struct process **); -+void process_destroy(struct process *); -+int process_kill(const struct process *, int signr); -+pid_t process_pid(const struct process *); -+const char *process_name(const struct process *); -+bool process_exited(struct process *); -+int process_status(const struct process *); -+void process_run(void); -+void process_wait(struct process *); -+ -+int count_crashes(pid_t); -+bool get_process_info(pid_t, struct process_info *); -+ -+/* These functions are thread-safe. */ -+char *process_status_msg(int); -+char *process_escape_args(char **argv); -+char *process_search_path(const char *); -+ -+#endif /* process.h */ -Index: openvswitch-2.17.2/include/internal/random.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/random.h -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2012 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef RANDOM_H -+#define RANDOM_H 1 -+ -+#include -+#include -+ -+void random_init(void); -+void random_set_seed(uint32_t); -+ -+void random_bytes(void *, size_t); -+uint32_t random_uint32(void); -+uint64_t random_uint64(void); -+ -+static inline int -+random_range(int max) -+{ -+ return random_uint32() % max; -+} -+ -+static inline uint8_t -+random_uint8(void) -+{ -+ return random_uint32(); -+} -+ -+static inline uint16_t -+random_uint16(void) -+{ -+ return random_uint32(); -+} -+ -+#endif /* random.h */ -Index: openvswitch-2.17.2/include/internal/simap.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/simap.h -@@ -0,0 +1,89 @@ -+/* -+ * Copyright (c) 2009, 2010, 2011, 2012, 2016, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef SIMAP_H -+#define SIMAP_H 1 -+ -+#include "openvswitch/hmap.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* A map from strings to unsigned integers. */ -+struct simap { -+ struct hmap map; /* Contains "struct simap_node"s. */ -+}; -+ -+struct simap_node { -+ struct hmap_node node; /* In struct simap's 'map' hmap. */ -+ char *name; -+ unsigned int data; -+}; -+ -+#define SIMAP_INITIALIZER(SIMAP) { HMAP_INITIALIZER(&(SIMAP)->map) } -+ -+#define SIMAP_FOR_EACH(SIMAP_NODE, SIMAP) \ -+ HMAP_FOR_EACH_INIT (SIMAP_NODE, node, &(SIMAP)->map, \ -+ BUILD_ASSERT_TYPE(SIMAP_NODE, struct simap_node *), \ -+ BUILD_ASSERT_TYPE(SIMAP, struct simap *)) -+ -+#define SIMAP_FOR_EACH_SAFE_SHORT(SIMAP_NODE, SIMAP) \ -+ HMAP_FOR_EACH_SAFE_SHORT_INIT (SIMAP_NODE, node, &(SIMAP)->map, \ -+ BUILD_ASSERT_TYPE(SIMAP_NODE, struct simap_node *), \ -+ BUILD_ASSERT_TYPE(SIMAP, struct simap *)) -+ -+#define SIMAP_FOR_EACH_SAFE_LONG(SIMAP_NODE, NEXT, SIMAP) \ -+ HMAP_FOR_EACH_SAFE_LONG_INIT (SIMAP_NODE, NEXT, node, &(SIMAP)->map, \ -+ BUILD_ASSERT_TYPE(SIMAP_NODE, struct simap_node *), \ -+ BUILD_ASSERT_TYPE(NEXT, struct simap_node *), \ -+ BUILD_ASSERT_TYPE(SIMAP, struct simap *)) -+ -+#define SIMAP_FOR_EACH_SAFE(...) \ -+ OVERLOAD_SAFE_MACRO(SIMAP_FOR_EACH_SAFE_LONG, \ -+ SIMAP_FOR_EACH_SAFE_SHORT, \ -+ 3, __VA_ARGS__) -+ -+void simap_init(struct simap *); -+void simap_destroy(struct simap *); -+void simap_swap(struct simap *, struct simap *); -+void simap_moved(struct simap *); -+void simap_clear(struct simap *); -+ -+bool simap_is_empty(const struct simap *); -+size_t simap_count(const struct simap *); -+ -+bool simap_put(struct simap *, const char *, unsigned int); -+unsigned int simap_increase(struct simap *, const char *, unsigned int); -+ -+unsigned int simap_get(const struct simap *, const char *); -+struct simap_node *simap_find(const struct simap *, const char *); -+struct simap_node *simap_find_len(const struct simap *, -+ const char *, size_t len); -+bool simap_contains(const struct simap *, const char *); -+ -+void simap_delete(struct simap *, struct simap_node *); -+bool simap_find_and_delete(struct simap *, const char *); -+ -+const struct simap_node **simap_sort(const struct simap *); -+bool simap_equal(const struct simap *, const struct simap *); -+uint32_t simap_hash(const struct simap *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* simap.h */ -Index: openvswitch-2.17.2/include/internal/skiplist.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/skiplist.h -@@ -0,0 +1,49 @@ -+/* Copyright (C) 2016 Hewlett Packard Enterprise Development LP -+ * All Rights Reserved. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); you may -+ * not use this file except in compliance with the License. You may obtain -+ * a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -+ * License for the specific language governing permissions and limitations -+ * under the License. -+ */ -+ -+#ifndef LIB_SKIPLIST_H_ -+#define LIB_SKIPLIST_H_ -+ -+#include -+#include -+#include -+ -+typedef int (skiplist_comparator)(const void *a, const void *b, -+ const void *conf); -+ -+struct skiplist_node; -+ -+struct skiplist; -+ -+#define SKIPLIST_FOR_EACH (SKIPLIST_NODE, SKIPLIST) \ -+ for (SKIPLIST_NODE = skiplist_first(SKIPLIST); \ -+ SKIPLIST_NODE; \ -+ SKIPLIST_NODE = skiplist_next(SKIPLIST_NODE)) -+ -+struct skiplist *skiplist_create(skiplist_comparator *object_comparator, -+ void *configuration); -+void skiplist_insert(struct skiplist *sl, const void *object); -+void *skiplist_delete(struct skiplist *sl, const void *object); -+struct skiplist_node *skiplist_find(struct skiplist *sl, const void *value); -+void *skiplist_get_data(struct skiplist_node *node); -+uint32_t skiplist_get_size(struct skiplist *sl); -+struct skiplist_node *skiplist_forward_to(struct skiplist *sl, -+ const void *value); -+struct skiplist_node *skiplist_first(struct skiplist *sl); -+struct skiplist_node *skiplist_next(struct skiplist_node *node); -+void skiplist_destroy(struct skiplist *sl, void (*func)(void *)); -+ -+#endif /* LIB_SKIPLIST_H_ */ -Index: openvswitch-2.17.2/include/internal/socket-util.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/socket-util.h -@@ -0,0 +1,185 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef SOCKET_UTIL_H -+#define SOCKET_UTIL_H 1 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "openvswitch/types.h" -+#include -+#include -+ -+struct ds; -+ -+int set_nonblocking(int fd); -+void xset_nonblocking(int fd); -+void setsockopt_tcp_nodelay(int fd); -+int set_dscp(int fd, int family, uint8_t dscp); -+ -+bool addr_is_ipv6(const char *host_name); -+int lookup_ip(const char *host_name, struct in_addr *address); -+int lookup_ipv6(const char *host_name, struct in6_addr *address); -+ -+int lookup_hostname(const char *host_name, struct in_addr *); -+ -+int get_socket_rcvbuf(int sock); -+int check_connection_completion(int fd); -+void drain_fd(int fd, size_t n_packets); -+ovs_be32 guess_netmask(ovs_be32 ip); -+ -+void inet_parse_host_port_tokens(char *s, char **hostp, char **portp); -+void inet_parse_port_host_tokens(char *s, char **portp, char **hostp); -+bool inet_parse_active(const char *target, int default_port, -+ struct sockaddr_storage *ssp, -+ bool resolve_host, bool *dns_failure); -+int inet_open_active(int style, const char *target, int default_port, -+ struct sockaddr_storage *ssp, int *fdp, uint8_t dscp); -+ -+bool inet_parse_passive(const char *target, int default_port, -+ struct sockaddr_storage *ssp); -+int inet_open_passive(int style, const char *target, int default_port, -+ struct sockaddr_storage *ssp, uint8_t dscp, -+ bool kernel_print_port); -+ -+bool inet_parse_address(const char *target, struct sockaddr_storage *); -+ -+int read_fully(int fd, void *, size_t, size_t *bytes_read); -+int write_fully(int fd, const void *, size_t, size_t *bytes_written); -+ -+int fsync_parent_dir(const char *file_name); -+int get_mtime(const char *file_name, struct timespec *mtime); -+ -+char *describe_fd(int fd); -+ -+/* Default value of dscp bits for connection between controller and manager. -+ * Value of IPTOS_PREC_INTERNETCONTROL = 0xc0 which is defined -+ * in is used. */ -+#define DSCP_DEFAULT (IPTOS_PREC_INTERNETCONTROL >> 2) -+ -+/* Functions for working with sockaddr that might contain an IPv4 or -+ * IPv6 address. */ -+bool sa_is_ip(const struct sockaddr *); -+uint16_t sa_get_port(const struct sockaddr *); -+struct in6_addr sa_get_address(const struct sockaddr *); -+void sa_format_address(const struct sockaddr *, struct ds *); -+void sa_format_address_nobracks(const struct sockaddr *, struct ds *); -+size_t sa_length(const struct sockaddr *); -+ -+/* Functions for working with sockaddr_storage that might contain an IPv4 or -+ * IPv6 address. */ -+bool ss_is_ip(const struct sockaddr_storage *); -+uint16_t ss_get_port(const struct sockaddr_storage *); -+struct in6_addr ss_get_address(const struct sockaddr_storage *); -+void ss_format_address(const struct sockaddr_storage *, struct ds *); -+void ss_format_address_nobracks(const struct sockaddr_storage *, struct ds *); -+size_t ss_length(const struct sockaddr_storage *); -+ -+const char *sock_strerror(int error); -+ -+#ifndef _WIN32 -+void xpipe(int fds[2]); -+void xpipe_nonblocking(int fds[2]); -+ -+int drain_rcvbuf(int fd); -+ -+int make_unix_socket(int style, bool nonblock, -+ const char *bind_path, const char *connect_path); -+int get_unix_name_len(const struct sockaddr_un *sun, socklen_t sun_len); -+ -+/* Universal sendmmsg and recvmmsg support on Linux. -+ * -+ * New enough Linux supports sendmmsg and recvmmsg, but older versions do not. -+ * We add the following infrastructure to allow all code on Linux to use -+ * sendmmsg and recvmmsg, regardless of platform support: -+ * -+ * - For platforms that lack these functions entirely, we emulate them. -+ * -+ * - With newer glibc but an old kernel, sendmmsg() and recvmmsg() fail with -+ * ENOSYS. To compensate, even if these functions appear to be available, we -+ * wrap them with handlers that use our emulation in this case. -+ */ -+#ifdef __linux__ -+#ifndef HAVE_STRUCT_MMSGHDR_MSG_LEN -+struct mmsghdr { -+ struct msghdr msg_hdr; -+ unsigned int msg_len; -+}; -+#endif -+ -+#ifndef HAVE_SENDMMSG -+int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int); -+int recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *); -+#else -+#define sendmmsg wrap_sendmmsg -+int wrap_sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int); -+#define recvmmsg wrap_recvmmsg -+int wrap_recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *); -+#endif -+#endif /* __linux__ */ -+ -+/* Helpers for calling ioctl() on an AF_INET socket. */ -+struct ifreq; -+int af_inet_ioctl(unsigned long int command, const void *arg); -+int af_inet_ifreq_ioctl(const char *name, struct ifreq *, -+ unsigned long int cmd, const char *cmd_name); -+ -+#define closesocket close -+#endif -+ -+#ifdef _WIN32 -+static inline int make_unix_socket(int style, bool nonblock, -+ const char *bind_path, -+ const char *connect_path) -+{ -+ return -EINVAL; -+} -+ -+/* Windows defines the 'optval' argument as char * instead of void *. */ -+#define setsockopt(sock, level, optname, optval, optlen) \ -+ rpl_setsockopt(sock, level, optname, optval, optlen) -+static inline int rpl_setsockopt(int sock, int level, int optname, -+ const void *optval, socklen_t optlen) -+{ -+ return (setsockopt)(sock, level, optname, (const char *)optval, optlen); -+} -+ -+#define getsockopt(sock, level, optname, optval, optlen) \ -+ rpl_getsockopt(sock, level, optname, optval, optlen) -+static inline int rpl_getsockopt(int sock, int level, int optname, -+ void *optval, socklen_t *optlen) -+{ -+ return (getsockopt)(sock, level, optname, (char *)optval, optlen); -+} -+#endif -+ -+/* In Windows platform, errno is not set for socket calls. -+ * The last error has to be gotten from WSAGetLastError(). */ -+static inline int sock_errno(void) -+{ -+#ifdef _WIN32 -+ return WSAGetLastError(); -+#else -+ return errno; -+#endif -+} -+ -+#endif /* socket-util.h */ -Index: openvswitch-2.17.2/include/internal/sort.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/sort.h -@@ -0,0 +1,26 @@ -+/* Copyright (c) 2009 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef SORT_H -+#define SORT_H 1 -+ -+#include -+ -+void sort(size_t count, -+ int (*compare)(size_t a, size_t b, void *aux), -+ void (*swap)(size_t a, size_t b, void *aux), -+ void *aux); -+ -+#endif /* sort.h */ -Index: openvswitch-2.17.2/include/internal/stopwatch.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/stopwatch.h -@@ -0,0 +1,59 @@ -+/* Copyright (c) 2017 Red Hat, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef STOPWATCH_H -+#define STOPWATCH_H 1 -+ -+#include -+ -+enum stopwatch_units { -+ SW_MS, -+ SW_US, -+ SW_NS, -+}; -+ -+struct stopwatch_stats { -+ unsigned long long count; /* Total number of samples. */ -+ enum stopwatch_units unit; /* Unit of following values. */ -+ unsigned long long max; /* Maximum value. */ -+ unsigned long long min; /* Minimum value. */ -+ double pctl_95; /* 95th percentile. */ -+ double ewma_50; /* Exponentially weighted moving average -+ (alpha 0.50). */ -+ double ewma_1; /* Exponentially weighted moving average -+ (alpha 0.01). */ -+}; -+ -+/* Create a new stopwatch. -+ * The "units" are not used for any calculations but are printed when -+ * statistics are requested. -+ */ -+void stopwatch_create(const char *name, enum stopwatch_units units); -+ -+/* Start a stopwatch. */ -+void stopwatch_start(const char *name, unsigned long long ts); -+ -+/* Stop a stopwatch. The elapsed time will be used for updating statistics -+ * for this stopwatch. -+ */ -+void stopwatch_stop(const char *name, unsigned long long ts); -+ -+/* Retrieve statistics calculated from collected samples */ -+bool stopwatch_get_stats(const char *name, struct stopwatch_stats *stats); -+ -+/* Block until all enqueued samples have been processed. */ -+void stopwatch_sync(void); -+ -+#endif /* stopwatch.h */ -Index: openvswitch-2.17.2/include/internal/stream-ssl.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/stream-ssl.h -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+#ifndef STREAM_SSL_H -+#define STREAM_SSL_H 1 -+ -+#include -+ -+bool stream_ssl_is_configured(void); -+void stream_ssl_set_private_key_file(const char *file_name); -+void stream_ssl_set_certificate_file(const char *file_name); -+void stream_ssl_set_ca_cert_file(const char *file_name, bool bootstrap); -+void stream_ssl_set_peer_ca_cert_file(const char *file_name); -+void stream_ssl_set_key_and_cert(const char *private_key_file, -+ const char *certificate_file); -+void stream_ssl_set_protocols(const char *arg); -+void stream_ssl_set_ciphers(const char *arg); -+ -+#define SSL_OPTION_ENUMS \ -+ OPT_SSL_PROTOCOLS, \ -+ OPT_SSL_CIPHERS -+ -+#define STREAM_SSL_LONG_OPTIONS \ -+ {"private-key", required_argument, NULL, 'p'}, \ -+ {"certificate", required_argument, NULL, 'c'}, \ -+ {"ca-cert", required_argument, NULL, 'C'}, \ -+ {"ssl-protocols", required_argument, NULL, OPT_SSL_PROTOCOLS}, \ -+ {"ssl-ciphers", required_argument, NULL, OPT_SSL_CIPHERS} -+ -+#define STREAM_SSL_OPTION_HANDLERS \ -+ case 'p': \ -+ stream_ssl_set_private_key_file(optarg); \ -+ break; \ -+ \ -+ case 'c': \ -+ stream_ssl_set_certificate_file(optarg); \ -+ break; \ -+ \ -+ case 'C': \ -+ stream_ssl_set_ca_cert_file(optarg, false); \ -+ break; \ -+ \ -+ case OPT_SSL_PROTOCOLS: \ -+ stream_ssl_set_protocols(optarg); \ -+ break; \ -+ \ -+ case OPT_SSL_CIPHERS: \ -+ stream_ssl_set_ciphers(optarg); \ -+ break; -+ -+#define STREAM_SSL_CASES \ -+ case 'p': case 'c': case 'C': case OPT_SSL_PROTOCOLS: case OPT_SSL_CIPHERS: -+ -+#endif /* stream-ssl.h */ -Index: openvswitch-2.17.2/include/internal/svec.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/svec.h -@@ -0,0 +1,80 @@ -+/* -+ * Copyright (c) 2008, 2009, 2011 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef SVEC_H -+#define SVEC_H 1 -+ -+#include -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct svec { -+ char **names; -+ size_t n; -+ size_t allocated; -+}; -+ -+#define SVEC_EMPTY_INITIALIZER { NULL, 0, 0 } -+ -+void svec_init(struct svec *); -+void svec_clone(struct svec *, const struct svec *); -+void svec_destroy(struct svec *); -+void svec_clear(struct svec *); -+bool svec_is_empty(const struct svec *); -+void svec_add(struct svec *, const char *); -+void svec_add_nocopy(struct svec *, char *); -+void svec_del(struct svec *, const char *); -+void svec_append(struct svec *, const struct svec *); -+void svec_terminate(struct svec *); -+void svec_sort(struct svec *); -+void svec_sort_unique(struct svec *); -+void svec_unique(struct svec *); -+void svec_compact(struct svec *); -+void svec_shuffle(struct svec *); -+void svec_diff(const struct svec *a, const struct svec *b, -+ struct svec *a_only, struct svec *both, struct svec *b_only); -+bool svec_contains(const struct svec *, const char *); -+bool svec_contains_unsorted(const struct svec *, const char *); -+size_t svec_find(const struct svec *, const char *); -+bool svec_is_sorted(const struct svec *); -+bool svec_is_unique(const struct svec *); -+const char *svec_get_duplicate(const struct svec *); -+void svec_swap(struct svec *a, struct svec *b); -+void svec_print(const struct svec *svec, const char *title); -+void svec_parse_words(struct svec *svec, const char *words); -+bool svec_equal(const struct svec *, const struct svec *); -+char *svec_join(const struct svec *, -+ const char *delimiter, const char *terminator); -+const char *svec_back(const struct svec *); -+void svec_pop_back(struct svec *); -+ -+/* Iterates over the names in SVEC, assigning each name in turn to NAME and its -+ * index to INDEX. */ -+#define SVEC_FOR_EACH(INDEX, NAME, SVEC) \ -+ for ((INDEX) = 0; \ -+ ((INDEX) < (SVEC)->n \ -+ ? (NAME) = (SVEC)->names[INDEX], 1 \ -+ : 0); \ -+ (INDEX)++) -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* svec.h */ -Index: openvswitch-2.17.2/include/internal/table.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/table.h -@@ -0,0 +1,139 @@ -+/* -+ * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef TABLE_H -+#define TABLE_H 1 -+ -+#include -+#include -+#include "openvswitch/compiler.h" -+#include "openvswitch/json.h" -+ -+struct ds; -+struct table_style; -+ -+/* Manipulating tables and their rows and columns. */ -+ -+struct table { -+ struct cell *cells; -+ struct column *columns; -+ size_t n_columns, allocated_columns; -+ size_t n_rows, allocated_rows; -+ size_t current_column; -+ char *caption; -+ bool timestamp; -+}; -+ -+void table_init(struct table *); -+void table_destroy(struct table *); -+void table_set_caption(struct table *, char *caption); -+void table_set_timestamp(struct table *, bool timestamp); -+ -+void table_add_column(struct table *, const char *heading, ...) -+ OVS_PRINTF_FORMAT(2, 3); -+void table_add_row(struct table *); -+ -+/* Table cells. */ -+ -+struct cell { -+ /* Literal text. */ -+ char *text; -+ -+ /* JSON. */ -+ struct json *json; -+ const struct ovsdb_type *type; -+}; -+ -+struct cell *table_add_cell(struct table *); -+ -+/* Table formatting. */ -+ -+enum table_format { -+ TF_TABLE, /* 2-d table. */ -+ TF_LIST, /* One cell per line, one row per paragraph. */ -+ TF_HTML, /* HTML table. */ -+ TF_CSV, /* Comma-separated lines. */ -+ TF_JSON /* JSON. */ -+}; -+ -+enum cell_format { -+ CF_STRING, /* String format. */ -+ CF_BARE, /* String format without most punctuation. */ -+ CF_JSON /* JSON. */ -+}; -+ -+struct table_style { -+ enum table_format format; /* TF_*. */ -+ enum cell_format cell_format; /* CF_*. */ -+ bool headings; /* Include headings? */ -+ int json_flags; /* CF_JSON: Flags for json_to_string(). */ -+ int max_column_width; /* CF_STRING: Limit for column width. */ -+}; -+ -+#define TABLE_STYLE_DEFAULT { TF_LIST, CF_STRING, true, JSSF_SORT, 0 } -+static const struct table_style table_style_default = TABLE_STYLE_DEFAULT; -+ -+#define TABLE_OPTION_ENUMS \ -+ OPT_NO_HEADINGS, \ -+ OPT_PRETTY, \ -+ OPT_BARE, \ -+ OPT_MAX_COLUMN_WIDTH -+ -+#define TABLE_LONG_OPTIONS \ -+ {"format", required_argument, NULL, 'f'}, \ -+ {"data", required_argument, NULL, 'd'}, \ -+ {"no-headings", no_argument, NULL, OPT_NO_HEADINGS}, \ -+ {"pretty", no_argument, NULL, OPT_PRETTY}, \ -+ {"bare", no_argument, NULL, OPT_BARE}, \ -+ {"max-column-width", required_argument, NULL, OPT_MAX_COLUMN_WIDTH} -+ -+#define TABLE_OPTION_HANDLERS(STYLE) \ -+ case 'f': \ -+ table_parse_format(STYLE, optarg); \ -+ break; \ -+ \ -+ case 'd': \ -+ table_parse_cell_format(STYLE, optarg); \ -+ break; \ -+ \ -+ case OPT_NO_HEADINGS: \ -+ (STYLE)->headings = false; \ -+ break; \ -+ \ -+ case OPT_PRETTY: \ -+ (STYLE)->json_flags |= JSSF_PRETTY; \ -+ break; \ -+ \ -+ case OPT_BARE: \ -+ (STYLE)->format = TF_LIST; \ -+ (STYLE)->cell_format = CF_BARE; \ -+ (STYLE)->headings = false; \ -+ break; \ -+ \ -+ case OPT_MAX_COLUMN_WIDTH: \ -+ (STYLE)->max_column_width = atoi(optarg); \ -+ break; -+ -+void table_parse_format(struct table_style *, const char *format); -+void table_parse_cell_format(struct table_style *, const char *format); -+ -+void table_print(const struct table *, const struct table_style *); -+void table_format(const struct table *, const struct table_style *, -+ struct ds *); -+void table_format_reset(void); -+void table_usage(void); -+ -+#endif /* table.h */ -Index: openvswitch-2.17.2/include/internal/unixctl.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/unixctl.h -@@ -0,0 +1,55 @@ -+/* -+ * Copyright (c) 2008, 2009, 2011 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef UNIXCTL_H -+#define UNIXCTL_H 1 -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Server for Unix domain socket control connection. */ -+struct unixctl_server; -+int unixctl_server_create(const char *path, struct unixctl_server **); -+void unixctl_server_run(struct unixctl_server *); -+void unixctl_server_wait(struct unixctl_server *); -+void unixctl_server_destroy(struct unixctl_server *); -+ -+const char *unixctl_server_get_path(const struct unixctl_server *); -+ -+/* Client for Unix domain socket control connection. */ -+struct jsonrpc; -+int unixctl_client_create(const char *path, struct jsonrpc **client); -+int unixctl_client_transact(struct jsonrpc *client, -+ const char *command, -+ int argc, char *argv[], -+ char **result, char **error); -+ -+/* Command registration. */ -+struct unixctl_conn; -+typedef void unixctl_cb_func(struct unixctl_conn *, -+ int argc, const char *argv[], void *aux); -+void unixctl_command_register(const char *name, const char *usage, -+ int min_args, int max_args, -+ unixctl_cb_func *cb, void *aux); -+void unixctl_command_reply_error(struct unixctl_conn *, const char *error); -+void unixctl_command_reply(struct unixctl_conn *, const char *body); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* unixctl.h */ -Index: openvswitch-2.17.2/include/internal/uuid.h -=================================================================== ---- /dev/null -+++ openvswitch-2.17.2/include/internal/uuid.h -@@ -0,0 +1,92 @@ -+/* Copyright (c) 2008, 2009, 2010, 2016, 2017 Nicira, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at: -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef UUID_H -+#define UUID_H 1 -+ -+#include "openvswitch/uuid.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* An initializer or expression for an all-zero UUID. */ -+#define UUID_ZERO ((struct uuid) { .parts = { 0, 0, 0, 0 } }) -+ -+/* Formats a UUID as a string, in the conventional format. -+ * -+ * Example: -+ * struct uuid uuid = ...; -+ * printf("This UUID is "UUID_FMT"\n", UUID_ARGS(&uuid)); -+ * -+ */ -+#define UUID_LEN 36 -+#define UUID_FMT "%08x-%04x-%04x-%04x-%04x%08x" -+#define UUID_ARGS(UUID) \ -+ ((unsigned int) ((UUID)->parts[0])), \ -+ ((unsigned int) ((UUID)->parts[1] >> 16)), \ -+ ((unsigned int) ((UUID)->parts[1] & 0xffff)), \ -+ ((unsigned int) ((UUID)->parts[2] >> 16)), \ -+ ((unsigned int) ((UUID)->parts[2] & 0xffff)), \ -+ ((unsigned int) ((UUID)->parts[3])) -+ -+/* Returns a hash value for 'uuid'. This hash value is the same regardless of -+ * whether we are running on a 32-bit or 64-bit or big-endian or little-endian -+ * architecture. */ -+static inline size_t -+uuid_hash(const struct uuid *uuid) -+{ -+ return uuid->parts[0]; -+} -+ -+/* Returns true if 'a == b', false otherwise. */ -+static inline bool -+uuid_equals(const struct uuid *a, const struct uuid *b) -+{ -+ return (a->parts[0] == b->parts[0] -+ && a->parts[1] == b->parts[1] -+ && a->parts[2] == b->parts[2] -+ && a->parts[3] == b->parts[3]); -+} -+ -+/* Returns the first 'n' hex digits of 'uuid', for 0 < 'n' <= 8. -+ * -+ * This is useful for displaying a few leading digits of the uuid, e.g. to -+ * display 4 digits: -+ * printf("%04x", uuid_prefix(uuid, 4)); -+ */ -+static inline unsigned int -+uuid_prefix(const struct uuid *uuid, int digits) -+{ -+ return (uuid->parts[0] >> (32 - 4 * digits)); -+} -+ -+void uuid_init(void); -+void uuid_generate(struct uuid *); -+struct uuid uuid_random(void); -+void uuid_zero(struct uuid *); -+bool uuid_is_zero(const struct uuid *); -+int uuid_compare_3way(const struct uuid *, const struct uuid *); -+bool uuid_from_string(struct uuid *, const char *); -+bool uuid_from_string_prefix(struct uuid *, const char *); -+int uuid_is_partial_string(const char *); -+int uuid_is_partial_match(const struct uuid *, const char *match); -+void uuid_set_bits_v4(struct uuid *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* uuid.h */ -Index: openvswitch-2.17.2/lib/bundle.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/bundle.h -+++ /dev/null -@@ -1,59 +0,0 @@ --/* Copyright (c) 2011, 2012, 2013, 2014, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef BUNDLE_H --#define BUNDLE_H 1 -- --#include --#include --#include --#include --#include --#include -- --#include "openvswitch/compiler.h" --#include "openflow/nicira-ext.h" --#include "openvswitch/ofp-errors.h" --#include "openvswitch/types.h" -- --struct ds; --struct flow; --struct flow_wildcards; --struct match; --struct ofpact_bundle; --struct ofpbuf; --struct ofputil_port_map; -- --/* NXAST_BUNDLE helper functions. -- * -- * See lib/ofp-actions.c for NXAST_BUNDLE specification. */ -- --#define BUNDLE_MAX_MEMBERS 2048 -- --ofp_port_t bundle_execute(const struct ofpact_bundle *, const struct flow *, -- struct flow_wildcards *wc, -- bool (*member_enabled)(ofp_port_t ofp_port, void *aux), -- void *aux); --enum ofperr bundle_check(const struct ofpact_bundle *, ofp_port_t max_ports, -- const struct match *); --char *bundle_parse(const char *, const struct ofputil_port_map *port_map, -- struct ofpbuf *ofpacts) OVS_WARN_UNUSED_RESULT; --char *bundle_parse_load(const char *, const struct ofputil_port_map *port_map, -- struct ofpbuf *ofpacts) -- OVS_WARN_UNUSED_RESULT; --void bundle_format(const struct ofpact_bundle *, -- const struct ofputil_port_map *, struct ds *); -- --#endif /* bundle.h */ -Index: openvswitch-2.17.2/lib/byte-order.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/byte-order.h -+++ /dev/null -@@ -1,148 +0,0 @@ --/* -- * Copyright (c) 2008, 2010, 2011, 2013, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --#ifndef BYTE_ORDER_H --#define BYTE_ORDER_H 1 -- --#include --#include --#include --#include --#include "openvswitch/types.h" -- --#ifndef __CHECKER__ --#if !(defined(_WIN32) || defined(htonll)) --static inline ovs_be64 --htonll(uint64_t n) --{ -- return htonl(1) == 1 ? n : ((uint64_t) htonl(n) << 32) | htonl(n >> 32); --} -- --static inline uint64_t --ntohll(ovs_be64 n) --{ -- return htonl(1) == 1 ? n : ((uint64_t) ntohl(n) << 32) | ntohl(n >> 32); --} --#endif /* !(defined(_WIN32) || defined(htonll)) */ --#else --/* Making sparse happy with these functions also makes them unreadable, so -- * don't bother to show it their implementations. */ --ovs_be64 htonll(uint64_t); --uint64_t ntohll(ovs_be64); --#endif -- --static inline ovs_be128 --hton128(const ovs_u128 src) --{ -- ovs_be128 dst; -- -- dst.be64.hi = htonll(src.u64.hi); -- dst.be64.lo = htonll(src.u64.lo); -- return dst; --} -- --static inline ovs_u128 --ntoh128(const ovs_be128 src) --{ -- ovs_u128 dst; -- -- dst.u64.hi = ntohll(src.be64.hi); -- dst.u64.lo = ntohll(src.be64.lo); -- return dst; --} -- --static inline uint32_t --uint32_byteswap(uint32_t crc) { -- return (((crc & 0x000000ff) << 24) | -- ((crc & 0x0000ff00) << 8) | -- ((crc & 0x00ff0000) >> 8) | -- ((crc & 0xff000000) >> 24)); --} -- --/* These macros may substitute for htons(), htonl(), and htonll() in contexts -- * where function calls are not allowed, such as case labels. They should not -- * be used elsewhere because all of them evaluate their argument many times. */ --#if defined(WORDS_BIGENDIAN) || __CHECKER__ --#define CONSTANT_HTONS(VALUE) ((OVS_FORCE ovs_be16) ((VALUE) & 0xffff)) --#define CONSTANT_HTONL(VALUE) ((OVS_FORCE ovs_be32) ((VALUE) & 0xffffffff)) --#define CONSTANT_HTONLL(VALUE) \ -- ((OVS_FORCE ovs_be64) ((VALUE) & UINT64_C(0xffffffffffffffff))) --#else --#define CONSTANT_HTONS(VALUE) \ -- (((((ovs_be16) (VALUE)) & 0xff00) >> 8) | \ -- ((((ovs_be16) (VALUE)) & 0x00ff) << 8)) --#define CONSTANT_HTONL(VALUE) \ -- (((((ovs_be32) (VALUE)) & 0x000000ff) << 24) | \ -- ((((ovs_be32) (VALUE)) & 0x0000ff00) << 8) | \ -- ((((ovs_be32) (VALUE)) & 0x00ff0000) >> 8) | \ -- ((((ovs_be32) (VALUE)) & 0xff000000) >> 24)) --#define CONSTANT_HTONLL(VALUE) \ -- (((((ovs_be64) (VALUE)) & UINT64_C(0x00000000000000ff)) << 56) | \ -- ((((ovs_be64) (VALUE)) & UINT64_C(0x000000000000ff00)) << 40) | \ -- ((((ovs_be64) (VALUE)) & UINT64_C(0x0000000000ff0000)) << 24) | \ -- ((((ovs_be64) (VALUE)) & UINT64_C(0x00000000ff000000)) << 8) | \ -- ((((ovs_be64) (VALUE)) & UINT64_C(0x000000ff00000000)) >> 8) | \ -- ((((ovs_be64) (VALUE)) & UINT64_C(0x0000ff0000000000)) >> 24) | \ -- ((((ovs_be64) (VALUE)) & UINT64_C(0x00ff000000000000)) >> 40) | \ -- ((((ovs_be64) (VALUE)) & UINT64_C(0xff00000000000000)) >> 56)) --#endif -- --/* Returns the ovs_be32 that you would get from: -- * -- * union { uint8_t b[4]; ovs_be32 be32; } x = { .b = { b0, b1, b2, b3 } }; -- * return x.be32; -- * -- * but without the undefined behavior. */ --static inline ovs_be32 --bytes_to_be32(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) --{ --#if WORDS_BIGENDIAN -- uint32_t x = ((uint32_t) b0 << 24) | (b1 << 16) | (b2 << 8) | b3; --#else -- uint32_t x = ((uint32_t) b3 << 24) | (b2 << 16) | (b1 << 8) | b0; --#endif -- return (OVS_FORCE ovs_be32) x; --} -- --/* These functions zero-extend big-endian values to longer ones, -- * or truncate long big-endian value to shorter ones. */ --#ifndef __CHECKER__ --#if WORDS_BIGENDIAN --static inline ovs_be32 be16_to_be32(ovs_be16 x) { return x; } --static inline ovs_be64 be16_to_be64(ovs_be16 x) { return x; } --static inline ovs_be64 be32_to_be64(ovs_be32 x) { return x; } --static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x; } --static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x; } --static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x; } --#else /* !WORDS_BIGENDIAN */ --static inline ovs_be32 be16_to_be32(ovs_be16 x) { return (ovs_be32) x << 16; } --static inline ovs_be64 be16_to_be64(ovs_be16 x) { return (ovs_be64) x << 48; } --static inline ovs_be64 be32_to_be64(ovs_be32 x) { return (ovs_be64) x << 32; } --static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x >> 32; } --static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x >> 48; } --static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x >> 16; } --#endif /* !WORDS_BIGENDIAN */ --#else /* __CHECKER__ */ --/* Making sparse happy with these functions also makes them unreadable, so -- * don't bother to show it their implementations. */ --ovs_be32 be16_to_be32(ovs_be16); --ovs_be64 be16_to_be64(ovs_be16); --ovs_be64 be32_to_be64(ovs_be32); --ovs_be32 be64_to_be32(ovs_be64); --ovs_be16 be64_to_be16(ovs_be64); --ovs_be16 be32_to_be16(ovs_be32); --#endif -- --#endif /* byte-order.h */ -Index: openvswitch-2.17.2/lib/colors.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/colors.h -+++ /dev/null -@@ -1,42 +0,0 @@ --/* -- * Copyright (c) 2016 6WIND S.A. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef COLORS_H --#define COLORS_H 1 -- --#include -- --struct colors { -- /* Color codes for various situation. Each of these is a fully formed -- * Select Graphic Rendition (SGR, "\33[...m") start string for the -- * appropriate color. -- */ -- char *actions; -- char *drop; -- char *learn; -- char *param; -- char *paren; -- char *special; -- char *value; -- -- /* SGR end string. */ -- char *end; --}; --extern struct colors colors; -- --void colors_init(bool enable_color); -- --#endif /* colors.h */ -Index: openvswitch-2.17.2/lib/command-line.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/command-line.h -+++ /dev/null -@@ -1,77 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef COMMAND_LINE_H --#define COMMAND_LINE_H 1 -- --/* Utilities for command-line parsing. */ -- --#include "openvswitch/compiler.h" -- --struct option; -- --/* Command handler context */ --struct ovs_cmdl_context { -- /* number of command line arguments */ -- int argc; -- /* array of command line arguments */ -- char **argv; -- /* private context data defined by the API user */ -- void *pvt; --}; -- --typedef void (*ovs_cmdl_handler)(struct ovs_cmdl_context *); -- --struct ovs_cmdl_command { -- const char *name; -- const char *usage; -- int min_args; -- int max_args; -- ovs_cmdl_handler handler; -- enum { OVS_RO, OVS_RW } mode; /* Does this command modify things? */ --}; -- --char *ovs_cmdl_long_options_to_short_options(const struct option *options); -- --struct ovs_cmdl_parsed_option { -- const struct option *o; -- char *arg; --}; --char *ovs_cmdl_parse_all(int argc, char *argv[], const struct option *, -- struct ovs_cmdl_parsed_option **, size_t *) -- OVS_WARN_UNUSED_RESULT; -- --char **ovs_cmdl_env_parse_all(int *argcp, char *argv_[], -- const char *env_options); -- --void ovs_cmdl_print_options(const struct option *options); --void ovs_cmdl_print_commands(const struct ovs_cmdl_command *commands); -- --void ovs_cmdl_run_command(struct ovs_cmdl_context *, -- const struct ovs_cmdl_command[]); --void ovs_cmdl_run_command_read_only(struct ovs_cmdl_context *, -- const struct ovs_cmdl_command[]); -- --void ovs_cmdl_proctitle_init(int argc, char **argv); --#if defined(__FreeBSD__) || defined(__NetBSD__) --#define ovs_cmdl_proctitle_set setproctitle --#else --void ovs_cmdl_proctitle_set(const char *, ...) -- OVS_PRINTF_FORMAT(1, 2); --#endif --void ovs_cmdl_proctitle_restore(void); -- --#endif /* command-line.h */ -Index: openvswitch-2.17.2/lib/crc32c.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/crc32c.h -+++ /dev/null -@@ -1,25 +0,0 @@ --/* -- * Copyright (c) 2012 The University of Waikato. -- * Author: Joe Stringer -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef CRC32C_H --#define CRC32C_H 1 -- --#include "openvswitch/types.h" -- --ovs_be32 crc32c(const uint8_t *data, size_t); -- --#endif /* crc32c.h */ -Index: openvswitch-2.17.2/lib/csum.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/csum.h -+++ /dev/null -@@ -1,59 +0,0 @@ --/* -- * Copyright (c) 2008, 2011, 2015 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef CSUM_H --#define CSUM_H 1 -- --#include --#include --#include "openvswitch/types.h" -- --struct in6_addr; -- --ovs_be16 csum(const void *, size_t); --uint32_t csum_continue(uint32_t partial, const void *, size_t); --ovs_be16 csum_finish(uint32_t partial); --ovs_be16 recalc_csum16(ovs_be16 old_csum, ovs_be16 old_u16, ovs_be16 new_u16); --ovs_be16 recalc_csum32(ovs_be16 old_csum, ovs_be32 old_u32, ovs_be32 new_u32); --ovs_be16 recalc_csum48(ovs_be16 old_csum, const struct eth_addr old_mac, -- const struct eth_addr new_mac); --ovs_be16 recalc_csum128(ovs_be16 old_csum, ovs_16aligned_be32 old_u32[4], -- const struct in6_addr *); -- --#ifndef __CHECKER__ --/* Adds the 16 bits in 'new' to the partial IP checksum 'partial' and returns -- * the updated checksum. (To start a new checksum, pass 0 for 'partial'. To -- * obtain the finished checksum, pass the return value to csum_finish().) */ --static inline uint32_t --csum_add16(uint32_t partial, ovs_be16 new) --{ -- return partial + new; --} -- --/* Adds the 32 bits in 'new' to the partial IP checksum 'partial' and returns -- * the updated checksum. (To start a new checksum, pass 0 for 'partial'. To -- * obtain the finished checksum, pass the return value to csum_finish().) */ --static inline uint32_t --csum_add32(uint32_t partial, ovs_be32 new) --{ -- return partial + (new >> 16) + (new & 0xffff); --} --#else --uint32_t csum_add16(uint32_t partial, ovs_be16); --uint32_t csum_add32(uint32_t partial, ovs_be32); --#endif -- --#endif /* csum.h */ -Index: openvswitch-2.17.2/lib/daemon.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/daemon.h -+++ /dev/null -@@ -1,183 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef DAEMON_H --#define DAEMON_H 1 -- --#include --#include --#include -- --/* This file provides an interface for utilities to run in the background -- * as daemons on POSIX platforms like Linux or as services on Windows platform. -- * Some of the functionalities defined in this file are only applicable to -- * POSIX platforms and some are applicable only on Windows. As such, the -- * function definitions unique to each platform are separated out with -- * ifdef macros. More descriptive comments on individual functions are provided -- * in daemon-unix.c (for POSIX platforms) and daemon-windows.c (for Windows). -- -- * The DAEMON_OPTION_ENUMS, DAEMON_LONG_OPTIONS and DAEMON_OPTION_HANDLERS -- * macros are useful for parsing command-line options in individual utilities. -- * For e.g., the command-line option "--monitor" is recognized on Linux -- * and results in calling the daemon_set_monitor() function. The same option is -- * not recognized on Windows platform. -- */ -- --#ifndef _WIN32 --#define DAEMON_OPTION_ENUMS \ -- OPT_DETACH, \ -- OPT_NO_SELF_CONFINEMENT, \ -- OPT_NO_CHDIR, \ -- OPT_OVERWRITE_PIDFILE, \ -- OPT_PIDFILE, \ -- OPT_MONITOR, \ -- OPT_USER_GROUP -- --#define DAEMON_LONG_OPTIONS \ -- {"detach", no_argument, NULL, OPT_DETACH}, \ -- {"no-self-confinement", no_argument, NULL, OPT_NO_SELF_CONFINEMENT}, \ -- {"no-chdir", no_argument, NULL, OPT_NO_CHDIR}, \ -- {"pidfile", optional_argument, NULL, OPT_PIDFILE}, \ -- {"overwrite-pidfile", no_argument, NULL, OPT_OVERWRITE_PIDFILE}, \ -- {"monitor", no_argument, NULL, OPT_MONITOR}, \ -- {"user", required_argument, NULL, OPT_USER_GROUP} -- --#define DAEMON_OPTION_HANDLERS \ -- case OPT_DETACH: \ -- set_detach(); \ -- break; \ -- \ -- case OPT_NO_SELF_CONFINEMENT: \ -- daemon_disable_self_confinement(); \ -- break; \ -- \ -- case OPT_NO_CHDIR: \ -- set_no_chdir(); \ -- break; \ -- \ -- case OPT_PIDFILE: \ -- set_pidfile(optarg); \ -- break; \ -- \ -- case OPT_OVERWRITE_PIDFILE: \ -- ignore_existing_pidfile(); \ -- break; \ -- \ -- case OPT_MONITOR: \ -- daemon_set_monitor(); \ -- break; \ -- \ -- case OPT_USER_GROUP: \ -- daemon_set_new_user(optarg); \ -- break; -- --#define DAEMON_OPTION_CASES \ -- case OPT_DETACH: \ -- case OPT_NO_SELF_CONFINEMENT: \ -- case OPT_NO_CHDIR: \ -- case OPT_PIDFILE: \ -- case OPT_OVERWRITE_PIDFILE: \ -- case OPT_MONITOR: \ -- case OPT_USER_GROUP: -- --void set_detach(void); --void daemon_set_monitor(void); --void set_no_chdir(void); --void ignore_existing_pidfile(void); --pid_t read_pidfile(const char *name); --#else --#define DAEMON_OPTION_ENUMS \ -- OPT_DETACH, \ -- OPT_NO_SELF_CONFINEMENT, \ -- OPT_NO_CHDIR, \ -- OPT_PIDFILE, \ -- OPT_PIPE_HANDLE, \ -- OPT_SERVICE, \ -- OPT_SERVICE_MONITOR, \ -- OPT_USER_GROUP -- --#define DAEMON_LONG_OPTIONS \ -- {"detach", no_argument, NULL, OPT_DETACH}, \ -- {"no-self-confinement", no_argument, NULL, OPT_NO_SELF_CONFINEMENT}, \ -- {"no-chdir", no_argument, NULL, OPT_NO_CHDIR}, \ -- {"pidfile", optional_argument, NULL, OPT_PIDFILE}, \ -- {"pipe-handle", required_argument, NULL, OPT_PIPE_HANDLE}, \ -- {"service", no_argument, NULL, OPT_SERVICE}, \ -- {"service-monitor", no_argument, NULL, OPT_SERVICE_MONITOR}, \ -- {"user", required_argument, NULL, OPT_USER_GROUP} -- --#define DAEMON_OPTION_HANDLERS \ -- case OPT_DETACH: \ -- set_detach(); \ -- break; \ -- \ -- case OPT_NO_SELF_CONFINEMENT: \ -- daemon_disable_self_confinement(); \ -- break; \ -- \ -- case OPT_NO_CHDIR: \ -- break; \ -- \ -- case OPT_PIDFILE: \ -- set_pidfile(optarg); \ -- break; \ -- \ -- case OPT_PIPE_HANDLE: \ -- set_pipe_handle(optarg); \ -- break; \ -- \ -- case OPT_SERVICE: \ -- set_detach(); \ -- break; \ -- \ -- case OPT_SERVICE_MONITOR: \ -- break; \ -- \ -- case OPT_USER_GROUP: \ -- daemon_set_new_user(optarg); -- --#define DAEMON_OPTION_CASES \ -- case OPT_DETACH: \ -- case OPT_NO_SELF_CONFINEMENT: \ -- case OPT_NO_CHDIR: \ -- case OPT_PIDFILE: \ -- case OPT_PIPE_HANDLE: \ -- case OPT_SERVICE: \ -- case OPT_SERVICE_MONITOR: \ -- case OPT_USER_GROUP: -- --void control_handler(DWORD request); --void set_pipe_handle(const char *pipe_handle); --void set_detach(void); --#endif /* _WIN32 */ -- --bool get_detach(void); --void daemon_save_fd(int fd); --void daemonize(void); --void daemonize_start(bool access_datapath); --void daemonize_complete(void); --void daemon_set_new_user(const char * user_spec); --void daemon_become_new_user(bool access_datapath); --void daemon_usage(void); --void daemon_disable_self_confinement(void); --bool daemon_should_self_confine(void); --void service_start(int *argcp, char **argvp[]); --void service_stop(void); --bool should_service_stop(void); --void set_pidfile(const char *name); --void close_standard_fds(void); -- --#endif /* daemon.h */ -Index: openvswitch-2.17.2/lib/db-ctl-base.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/db-ctl-base.h -+++ /dev/null -@@ -1,282 +0,0 @@ --/* -- * Copyright (c) 2015, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef DB_CTL_BASE_H --#define DB_CTL_BASE_H 1 -- --#include "openvswitch/compiler.h" --#include "openvswitch/dynamic-string.h" --#include "openvswitch/shash.h" -- --struct ctl_context; --struct option; --struct ovsdb_idl; --struct ovsdb_idl_row; --struct ovsdb_idl_txn; --struct ovsdb_symbol_table; --struct table; -- --/* This library module contains the common parts for ovsdb manipulation -- * (structs, commands and functions). To utilize this module, user must -- * define the following: -- * -- * - the command syntaxes for each command. (See 'struct ctl_command_syntax' -- * for more info) and regiters them using ctl_register_commands(). -- * -- * - the *ctl command context by inheriting the 'struct ctl_context' for -- * additional commands implemented by user. (See 'struct ctl_context' for -- * more info) --*/ -- --/* ctl_fatal() also logs the error, so it is preferred in this file. */ --#define ovs_fatal please_use_ctl_fatal_instead_of_ovs_fatal -- --struct ctl_table_class; --struct ovsdb_idl_class; --struct ovsdb_idl_table_class; --struct cmd_show_table; -- --/* ctl_init() figures out the number of tables on its own and flags an error if -- * 'ctl_classes' was defined with the wrong number of elements. */ --#define ctl_init(idl_class, table_classes, ctl_classes, cmd_show_table, \ -- ctl_exit_func) \ -- (BUILD_ASSERT(ARRAY_SIZE(table_classes) == ARRAY_SIZE(ctl_classes)), \ -- ctl_init__(idl_class, ctl_classes, cmd_show_table, ctl_exit_func)) --void ctl_init__(const struct ovsdb_idl_class *, const struct ctl_table_class *, -- const struct cmd_show_table *cmd_show_tables, -- void (*ctl_exit_func)(int status)); --char *ctl_default_db(void); --void ctl_error(struct ctl_context *, const char *, ...) --OVS_PRINTF_FORMAT(2, 3); --OVS_NO_RETURN void ctl_fatal(const char *, ...) OVS_PRINTF_FORMAT(1, 2); -- --/* *ctl command syntax structure, to be defined by each command implementation. -- * -- * Execution Path -- * ============== -- * -- * Three stylized functions accompany each of these data structures: -- * -- * "pre-run" "run" "post-run" -- * --------------- ------------ ----------------- -- * *ctl ->prerequisites ->run ->postprocess -- * -- * Any *ctl command implementation should go through the following execution -- * path: -- * -- * 1. parses user command-line input and finds the corresponding syntax -- * structures. -- * -- * 2. calls prerequisites() for getting the columns or tables used by each -- * command. -- * -- * 3. calls run() to execute each command and to generate output. -- * -- * 4. calls postprocess() after output has been committed. (Only needed -- * by 'create' command sofar) -- * -- * Execution Context -- * ================= -- * -- * Each of the stylized functions requires the 'struct ctl_context' as input -- * to provide context e.g. command-line arguments, table to be modified. User -- * may define more specific context (by inheriting 'struct ctl_context') and -- * write stylized functions that use it. In that case, CONTAINER_OF() can -- * be used to cast the generic context to the specific one. -- * -- * */ --struct ctl_command_syntax { -- const char *name; /* e.g. "add-br" */ -- int min_args; /* Min number of arguments following name. */ -- int max_args; /* Max number of arguments following name. */ -- -- /* Names that roughly describe the arguments that the command -- * uses. These should be similar to the names displayed in the -- * man page or in the help output. */ -- const char *arguments; -- -- /* If nonnull, calls ovsdb_idl_add_column() or ovsdb_idl_add_table() for -- * each column or table in ctx->idl that it uses. */ -- void (*prerequisites)(struct ctl_context *ctx); -- -- /* Does the actual work of the command and puts the command's output, if -- * any, in ctx->output or ctx->table. -- * -- * Alternatively, if some prerequisite of the command is not met and the -- * caller should wait for something to change and then retry, it may set -- * ctx->try_again to true. (Only the "wait-until" command currently does -- * this.) */ -- void (*run)(struct ctl_context *ctx); -- -- /* If nonnull, called after the transaction has been successfully -- * committed. ctx->output is the output from the "run" function, which -- * this function may modify and otherwise postprocess as needed. (Only the -- * "create" command currently does any postprocessing.) */ -- void (*postprocess)(struct ctl_context *ctx); -- -- /* A comma-separated list of supported options, e.g. "--a,--b", or the -- * empty string if the command does not support any options. -- * -- * Arguments are determined by appending special characters to option -- * names: -- * -- * - Append "=" (e.g. "--id=") for a required argument. -- * -- * - Append "?" (e.g. "--ovs?") for an optional argument. -- * -- * - Otherwise an option does not accept an argument. */ -- const char *options; -- -- enum { RO, RW } mode; /* Does this command modify the database? */ --}; -- --/* A command extracted from command-line input plus the structs for -- * output generation. */ --struct ctl_command { -- /* Data that remains constant after initialization. */ -- const struct ctl_command_syntax *syntax; -- int argc; -- char **argv; -- struct shash options; -- -- /* Data modified by commands. */ -- struct ds output; -- struct table *table; --}; -- --bool ctl_might_write_to_db(const struct ctl_command *, size_t n); --const char *ctl_get_db_cmd_usage(void); -- --const char *ctl_list_db_tables_usage(void); --void ctl_print_commands(void); --void ctl_print_options(const struct option *); --void ctl_add_cmd_options(struct option **, size_t *n_options_p, -- size_t *allocated_options_p, int opt_val); --void ctl_register_commands(const struct ctl_command_syntax *); --char * OVS_WARN_UNUSED_RESULT ctl_parse_commands( -- int argc, char *argv[], struct shash *local_options, -- struct ctl_command **commandsp, size_t *n_commandsp); -- --/* Sometimes, it is desirable to print the table with weak reference to -- * rows in a 'cmd_show_table' table. In that case, the 'weak_ref_table' -- * should be used and user must define all variables. */ --struct weak_ref_table { -- const struct ovsdb_idl_table_class *table; -- const struct ovsdb_idl_column *name_column; -- /* This colum must be a weak reference to the owning -- * 'struct cmd_show_table''s table row. */ -- const struct ovsdb_idl_column *wref_column; --}; -- --/* This struct is for organizing the 'show' command output where: -- * -- * - 'table' is the table to show. -- * -- * - if 'name_column' is not null, it is used as the name for each row -- * in 'table'. -- * -- * - 'columns[]' allows user to specify the print of additional columns -- * in 'table'. -- * -- * - if 'wref_table' is populated, print 'wref_table.name_column' for -- * each row in table 'wref_table.table' that has a reference to 'table' -- * in 'wref_table.wref_column'. Every field must be populated. -- * -- * */ --struct cmd_show_table { -- const struct ovsdb_idl_table_class *table; -- const struct ovsdb_idl_column *name_column; -- const struct ovsdb_idl_column *columns[4]; /* Seems like a good number. */ -- const struct weak_ref_table wref_table; --}; -- -- --/* The base context struct for conducting the common database -- * operations (commands listed in 'db_ctl_commands'). User should -- * define the per-schema context by inheriting this struct as base. -- * -- * Database Caches -- * =============== -- * -- * User may implement caches for contents of the database to facilitate -- * specific commands. In that case, the common commands defined in -- * 'db_ctl_commands' that may invalidate the cache must call the -- * invalidate_cache(). -- * -- **/ --struct ctl_context { -- /* Read-only. */ -- int argc; -- char **argv; -- struct shash options; -- -- /* Modifiable state. */ -- char *error; -- struct ds output; -- struct table *table; -- struct ovsdb_idl *idl; -- struct ovsdb_idl_txn *txn; -- struct ovsdb_symbol_table *symtab; -- -- /* For implementation with a cache of the contents of the database, -- * this function will be called when the database is changed and the -- * change makes the cache no longer valid. */ -- void (*invalidate_cache_cb)(struct ctl_context *); -- -- /* A command may set this member to true if some prerequisite is not met -- * and the caller should wait for something to change and then retry. */ -- bool try_again; --}; -- --void ctl_context_init_command(struct ctl_context *, struct ctl_command *); --void ctl_context_init(struct ctl_context *, struct ctl_command *, -- struct ovsdb_idl *, struct ovsdb_idl_txn *, -- struct ovsdb_symbol_table *, -- void (*invalidate_cache)(struct ctl_context *)); --void ctl_context_done_command(struct ctl_context *, struct ctl_command *); --void ctl_context_done(struct ctl_context *, struct ctl_command *); -- --/* A way to identify a particular row in the database based on a user-provided -- * string. If all fields are NULL, the struct is ignored. Otherwise, -- * 'name_column' designates a column whose table is searched for rows that -- * match with the user string. If 'key' is NULL, then 'name_column' should be -- * a string or integer-valued column; otherwise it should be a map from a -- * string to one of those types and the value corresponding to 'key' is what is -- * matched. If a matching row is found, then: -- * -- * - If 'uuid_column' is NULL, the matching row is the final row. -- * -- * - Otherwise 'uuid_column' must designate a UUID-typed column whose value -- * refers to exactly one row, which is the final row. -- */ --struct ctl_row_id { -- const struct ovsdb_idl_column *name_column; -- const char *key; -- const struct ovsdb_idl_column *uuid_column; --}; -- --struct ctl_table_class { -- struct ctl_row_id row_ids[4]; --}; -- --char *ctl_get_row(struct ctl_context *, const struct ovsdb_idl_table_class *, -- const char *record_id, bool must_exist, -- const struct ovsdb_idl_row **); -- --char *ctl_set_column(const char *table_name, const struct ovsdb_idl_row *, -- const char *arg, struct ovsdb_symbol_table *); -- --#endif /* db-ctl-base.h */ -Index: openvswitch-2.17.2/lib/dhparams.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dhparams.h -+++ /dev/null -@@ -1,26 +0,0 @@ --/* -- * Copyright (c) 2008, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef DHPARAMS_H --#define DHPARAMS_H 1 -- --#include --#include -- --DH *get_dh2048(void); --DH *get_dh4096(void); -- --#endif /* dhparams.h */ -Index: openvswitch-2.17.2/lib/dirs.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dirs.h -+++ /dev/null -@@ -1,35 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef DIRS_H --#define DIRS_H 1 -- --#ifdef __cplusplus --extern "C" { --#endif -- --const char *ovs_sysconfdir(void); /* /usr/local/etc */ --const char *ovs_pkgdatadir(void); /* /usr/local/share/openvswitch */ --const char *ovs_rundir(void); /* /usr/local/var/run/openvswitch */ --const char *ovs_logdir(void); /* /usr/local/var/log/openvswitch */ --const char *ovs_dbdir(void); /* /usr/local/etc/openvswitch */ --const char *ovs_bindir(void); /* /usr/local/bin */ -- --#ifdef __cplusplus --} --#endif -- --#endif /* dirs.h */ -Index: openvswitch-2.17.2/lib/fatal-signal.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/fatal-signal.h -+++ /dev/null -@@ -1,52 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2013 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef FATAL_SIGNAL_H --#define FATAL_SIGNAL_H 1 -- --#ifndef _WIN32 --#include --#endif --#include -- --/* Basic interface. */ --void fatal_signal_init(void); --void fatal_signal_add_hook(void (*hook_cb)(void *aux), -- void (*cancel_cb)(void *aux), void *aux, -- bool run_at_exit); --void fatal_signal_fork(void); --void fatal_signal_run(void); --void fatal_signal_wait(void); --void fatal_ignore_sigpipe(void); --void fatal_signal_atexit_handler(void); -- --/* Convenience functions for unlinking files upon termination. -- * -- * These functions also unlink the files upon normal process termination via -- * exit(). */ --void fatal_signal_add_file_to_unlink(const char *); --void fatal_signal_remove_file_to_unlink(const char *); --int fatal_signal_unlink_file_now(const char *); -- --/* Interface for other code that catches one of our signals and needs to pass -- * it through. */ --void fatal_signal_handler(int sig_nr); -- --#ifndef _WIN32 --void fatal_signal_block(sigset_t *prev_mask); --#endif -- --#endif /* fatal-signal.h */ -Index: openvswitch-2.17.2/lib/hash-aarch64.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/hash-aarch64.h -+++ /dev/null -@@ -1,150 +0,0 @@ --/* -- * Copyright (c) 2019 Arm Limited -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements HASH operation primitives on aarch64. */ --#ifndef HASH_AARCH64_H --#define HASH_AARCH64_H 1 -- --#ifndef HASH_H --#error "This header should only be included indirectly via hash.h." --#endif -- --#ifdef __cplusplus --extern "C" { --#endif -- --#include -- --static inline uint32_t hash_add(uint32_t hash, uint32_t data) --{ -- return __crc32cw(hash, data); --} -- --/* Add the halves of 'data' in the memory order. */ --static inline uint32_t hash_add64(uint32_t hash, uint64_t data) --{ -- return __crc32cd(hash, data); --} -- --static inline uint32_t hash_finish(uint32_t hash, uint64_t final) --{ -- /* The finishing multiplier 0x805204f3 has been experimentally -- * derived to pass the testsuite hash tests. */ -- hash = __crc32cd(hash, final) * 0x805204f3; -- return hash ^ hash >> 16; /* Increase entropy in LSBs. */ --} -- --/* Returns the hash of the 'n' 32-bit words at 'p_', starting from 'basis'. -- * We access 'p_' as a uint64_t pointer. -- * -- * This is inlined for the compiler to have access to the 'n_words', which -- * in many cases is a constant. */ --static inline uint32_t --hash_words_inline(const uint32_t p_[], size_t n_words, uint32_t basis) --{ -- const uint64_t *p = (const void *)p_; -- uint32_t hash1 = basis; -- uint32_t hash2 = 0; -- uint32_t hash3 = n_words; -- const uint32_t *endp = (const uint32_t *)p + n_words; -- const uint64_t *limit = p + n_words / 2 - 3; -- -- while (p <= limit) { -- hash1 = __crc32cd(hash1, p[0]); -- hash2 = __crc32cd(hash2, p[1]); -- hash3 = __crc32cd(hash3, p[2]); -- p += 3; -- } -- switch (endp - (const uint32_t *)p) { -- case 1: -- hash1 = __crc32cw(hash1, *(const uint32_t *)&p[0]); -- break; -- case 2: -- hash1 = __crc32cd(hash1, p[0]); -- break; -- case 3: -- hash1 = __crc32cd(hash1, p[0]); -- hash2 = __crc32cw(hash2, *(const uint32_t *)&p[1]); -- break; -- case 4: -- hash1 = __crc32cd(hash1, p[0]); -- hash2 = __crc32cd(hash2, p[1]); -- break; -- case 5: -- hash1 = __crc32cd(hash1, p[0]); -- hash2 = __crc32cd(hash2, p[1]); -- hash3 = __crc32cw(hash3, *(const uint32_t *)&p[2]); -- break; -- } -- return hash_finish(hash1, (uint64_t)hash2 << 32 | hash3); --} -- --/* A simpler version for 64-bit data. -- * 'n_words' is the count of 64-bit words, basis is 64 bits. */ --static inline uint32_t --hash_words64_inline(const uint64_t p[], size_t n_words, uint32_t basis) --{ -- uint32_t hash1 = basis; -- uint32_t hash2 = 0; -- uint32_t hash3 = n_words; -- const uint64_t *endp = p + n_words; -- const uint64_t *limit = endp - 3; -- -- while (p <= limit) { -- hash1 = __crc32cd(hash1, p[0]); -- hash2 = __crc32cd(hash2, p[1]); -- hash3 = __crc32cd(hash3, p[2]); -- p += 3; -- } -- switch (endp - p) { -- case 1: -- hash1 = __crc32cd(hash1, p[0]); -- break; -- case 2: -- hash1 = __crc32cd(hash1, p[0]); -- hash2 = __crc32cd(hash2, p[1]); -- break; -- } -- return hash_finish(hash1, (uint64_t)hash2 << 32 | hash3); --} -- --static inline uint32_t hash_uint64_basis(const uint64_t x, -- const uint32_t basis) --{ -- /* '23' chosen to mix bits enough for the test-hash to pass. */ -- return hash_finish(hash_add64(basis, x), 23); --} -- --static inline uint32_t hash_uint64(const uint64_t x) --{ -- return hash_uint64_basis(x, 0); --} -- --static inline uint32_t hash_2words(uint32_t x, uint32_t y) --{ -- return hash_uint64((uint64_t)y << 32 | x); --} -- --static inline uint32_t hash_pointer(const void *p, uint32_t basis) --{ -- return hash_uint64_basis((uint64_t) (uintptr_t) p, basis); --} -- --#ifdef __cplusplus --} --#endif -- --#endif /* hash-aarch64.h */ -Index: openvswitch-2.17.2/lib/hmapx.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/hmapx.h -+++ /dev/null -@@ -1,86 +0,0 @@ --/* -- * Copyright (c) 2011, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef HMAPX_H --#define HMAPX_H -- --#include "openvswitch/hmap.h" -- --struct hmapx_node { -- struct hmap_node hmap_node; -- void *data; --}; -- --/* A set of "void *" pointers. */ --struct hmapx { -- struct hmap map; --}; -- --#define HMAPX_INITIALIZER(HMAPX) { HMAP_INITIALIZER(&(HMAPX)->map) } -- --/* Basics. */ --void hmapx_init(struct hmapx *); --void hmapx_destroy(struct hmapx *); --void hmapx_clone(struct hmapx *, const struct hmapx *); --void hmapx_swap(struct hmapx *, struct hmapx *); --void hmapx_moved(struct hmapx *); -- --/* Count. */ --bool hmapx_is_empty(const struct hmapx *); --size_t hmapx_count(const struct hmapx *); -- --/* Insertion. */ --struct hmapx_node *hmapx_add(struct hmapx *, void *); --void hmapx_add_assert(struct hmapx *, void *); -- --/* Deletion. */ --void hmapx_clear(struct hmapx *); --void hmapx_delete(struct hmapx *, struct hmapx_node *); --bool hmapx_find_and_delete(struct hmapx *, const void *); --void hmapx_find_and_delete_assert(struct hmapx *, const void *); -- --/* Search. */ --struct hmapx_node *hmapx_find(const struct hmapx *, const void *); --bool hmapx_contains(const struct hmapx *, const void *); --bool hmapx_equals(const struct hmapx *, const struct hmapx *); -- --/* Iteration. */ -- --/* Iterates through every hmapx_node in HMAPX. */ --#define HMAPX_FOR_EACH(NODE, HMAPX) \ -- HMAP_FOR_EACH_INIT(NODE, hmap_node, &(HMAPX)->map, \ -- BUILD_ASSERT_TYPE(NODE, struct hmapx_node *), \ -- BUILD_ASSERT_TYPE(HMAPX, struct hmapx *)) -- --/* Safe when NODE may be freed (not needed when NODE may be removed from the -- * hash map but its members remain accessible and intact). */ --#define HMAPX_FOR_EACH_SAFE_SHORT(NODE, HMAPX) \ -- HMAP_FOR_EACH_SAFE_SHORT_INIT (NODE, hmap_node, &(HMAPX)->map, \ -- BUILD_ASSERT_TYPE(NODE, struct hmapx_node *), \ -- BUILD_ASSERT_TYPE(HMAPX, struct hmapx *)) -- --#define HMAPX_FOR_EACH_SAFE_LONG(NODE, NEXT, HMAPX) \ -- HMAP_FOR_EACH_SAFE_LONG_INIT (NODE, NEXT, hmap_node, &(HMAPX)->map, \ -- BUILD_ASSERT_TYPE(NODE, struct hmapx_node *), \ -- BUILD_ASSERT_TYPE(NEXT, struct hmapx_node *), \ -- BUILD_ASSERT_TYPE(HMAPX, struct hmapx *)) -- --#define HMAPX_FOR_EACH_SAFE(...) \ -- OVERLOAD_SAFE_MACRO(HMAPX_FOR_EACH_SAFE_LONG, \ -- HMAPX_FOR_EACH_SAFE_SHORT, \ -- 3, __VA_ARGS__) -- --#endif /* hmapx.h */ -Index: openvswitch-2.17.2/lib/id-pool.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/id-pool.h -+++ /dev/null -@@ -1,45 +0,0 @@ --/* -- * Copyright (c) 2014 Nicira, Inc. -- * Copyright (c) 2014 Netronome. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef ID_POOL_H --#define ID_POOL_H -- --#include --#include --#include -- --struct id_pool; -- --struct id_pool *id_pool_create(uint32_t base, uint32_t n_ids); --void id_pool_destroy(struct id_pool *); --bool id_pool_alloc_id(struct id_pool *, uint32_t *id); --void id_pool_free_id(struct id_pool *, uint32_t id); --void id_pool_add(struct id_pool *, uint32_t id); -- --/* -- * ID pool. -- * ======== -- * -- * Pool of unique 32bit ids. -- * Allocation always returns the lowest available id. -- * -- * Thread-safety -- * ============= -- * -- * APIs are not thread safe. -- */ --#endif /* id-pool.h */ -Index: openvswitch-2.17.2/lib/jsonrpc.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/jsonrpc.h -+++ /dev/null -@@ -1,153 +0,0 @@ --/* -- * Copyright (c) 2009, 2010, 2012, 2013, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef JSONRPC_H --#define JSONRPC_H 1 -- --/* This is an implementation of the JSON-RPC 1.0 specification defined at -- * http://json-rpc.org/wiki/specification. */ -- --#include --#include --#include "openvswitch/types.h" -- --struct json; --struct jsonrpc_msg; --struct pstream; --struct reconnect_stats; --struct stream; --struct svec; -- --/* API for a JSON-RPC stream. */ -- --/* Default port numbers. -- * -- * OVSDB_OLD_PORT defines the original port number used by OVS. -- * OVSDB_PORT defines the official port number assigned by IANA. */ --#define OVSDB_OLD_PORT 6632 --#define OVSDB_PORT 6640 -- --int jsonrpc_stream_open(const char *name, struct stream **, uint8_t dscp); --int jsonrpc_pstream_open(const char *name, struct pstream **, uint8_t dscp); -- --struct jsonrpc *jsonrpc_open(struct stream *); --void jsonrpc_close(struct jsonrpc *); -- --void jsonrpc_run(struct jsonrpc *); --void jsonrpc_wait(struct jsonrpc *); -- --int jsonrpc_get_status(const struct jsonrpc *); --size_t jsonrpc_get_backlog(const struct jsonrpc *); --void jsonrpc_set_backlog_threshold(struct jsonrpc *, size_t max_n_msgs, -- size_t max_backlog_bytes); -- --unsigned int jsonrpc_get_received_bytes(const struct jsonrpc *); --const char *jsonrpc_get_name(const struct jsonrpc *); -- --int jsonrpc_send(struct jsonrpc *, struct jsonrpc_msg *); --int jsonrpc_recv(struct jsonrpc *, struct jsonrpc_msg **); --void jsonrpc_recv_wait(struct jsonrpc *); -- --int jsonrpc_send_block(struct jsonrpc *, struct jsonrpc_msg *); --int jsonrpc_recv_block(struct jsonrpc *, struct jsonrpc_msg **); --int jsonrpc_transact_block(struct jsonrpc *, struct jsonrpc_msg *, -- struct jsonrpc_msg **); -- --/* Messages. */ --enum jsonrpc_msg_type { -- JSONRPC_REQUEST, /* Request. */ -- JSONRPC_NOTIFY, /* Notification. */ -- JSONRPC_REPLY, /* Successful reply. */ -- JSONRPC_ERROR /* Error reply. */ --}; -- --struct jsonrpc_msg { -- enum jsonrpc_msg_type type; -- char *method; /* Request or notification only. */ -- struct json *params; /* Request or notification only. */ -- struct json *result; /* Successful reply only. */ -- struct json *error; /* Error reply only. */ -- struct json *id; /* Request or reply only. */ --}; -- --struct jsonrpc_msg *jsonrpc_create_request(const char *method, -- struct json *params, -- struct json **idp); --struct jsonrpc_msg *jsonrpc_create_notify(const char *method, -- struct json *params); --struct jsonrpc_msg *jsonrpc_create_reply(struct json *result, -- const struct json *id); --struct jsonrpc_msg *jsonrpc_create_error(struct json *error, -- const struct json *id); -- --struct jsonrpc_msg *jsonrpc_msg_clone(const struct jsonrpc_msg *); -- --const char *jsonrpc_msg_type_to_string(enum jsonrpc_msg_type); --char *jsonrpc_msg_is_valid(const struct jsonrpc_msg *); --void jsonrpc_msg_destroy(struct jsonrpc_msg *); -- --char *jsonrpc_msg_from_json(struct json *, struct jsonrpc_msg **); --struct json *jsonrpc_msg_to_json(struct jsonrpc_msg *); -- --char *jsonrpc_msg_to_string(const struct jsonrpc_msg *); -- --/* A JSON-RPC session with reconnection. */ -- --struct jsonrpc_session *jsonrpc_session_open(const char *name, bool retry); --struct jsonrpc_session *jsonrpc_session_open_multiple(const struct svec *, -- bool retry); --struct jsonrpc_session *jsonrpc_session_open_unreliably(struct jsonrpc *, -- uint8_t); --void jsonrpc_session_close(struct jsonrpc_session *); -- --struct jsonrpc *jsonrpc_session_steal(struct jsonrpc_session *); --void jsonrpc_session_replace(struct jsonrpc_session *, struct jsonrpc *); -- --void jsonrpc_session_run(struct jsonrpc_session *); --void jsonrpc_session_wait(struct jsonrpc_session *); -- --size_t jsonrpc_session_get_backlog(const struct jsonrpc_session *); --const char *jsonrpc_session_get_name(const struct jsonrpc_session *); --size_t jsonrpc_session_get_n_remotes(const struct jsonrpc_session *); -- --int jsonrpc_session_send(struct jsonrpc_session *, struct jsonrpc_msg *); --struct jsonrpc_msg *jsonrpc_session_recv(struct jsonrpc_session *); --void jsonrpc_session_recv_wait(struct jsonrpc_session *); -- --bool jsonrpc_session_is_alive(const struct jsonrpc_session *); --bool jsonrpc_session_is_connected(const struct jsonrpc_session *); --unsigned int jsonrpc_session_get_seqno(const struct jsonrpc_session *); --int jsonrpc_session_get_status(const struct jsonrpc_session *); --int jsonrpc_session_get_last_error(const struct jsonrpc_session *); --void jsonrpc_session_get_reconnect_stats(const struct jsonrpc_session *, -- struct reconnect_stats *); -- --void jsonrpc_session_enable_reconnect(struct jsonrpc_session *); --void jsonrpc_session_force_reconnect(struct jsonrpc_session *); --void jsonrpc_session_reset_backoff(struct jsonrpc_session *); -- --void jsonrpc_session_set_max_backoff(struct jsonrpc_session *, -- int max_backoff); --void jsonrpc_session_set_probe_interval(struct jsonrpc_session *, -- int probe_interval); --void jsonrpc_session_set_dscp(struct jsonrpc_session *, -- uint8_t dscp); --void jsonrpc_session_set_backlog_threshold(struct jsonrpc_session *, -- size_t max_n_msgs, -- size_t max_backlog_bytes); --const char *jsonrpc_session_get_id(const struct jsonrpc_session *); -- --#endif /* jsonrpc.h */ -Index: openvswitch-2.17.2/lib/memory.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/memory.h -+++ /dev/null -@@ -1,60 +0,0 @@ --/* -- * Copyright (c) 2012 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef MEMORY_H --#define MEMORY_H 1 -- --/* Memory usage monitor. -- * -- * This is intended to be called as part of a daemon's main loop. After some -- * time to allow the daemon to allocate an initial memory usage, it logs some -- * memory usage information (most of which must actually be provided by the -- * client). At intervals, if the daemon's memory usage has grown -- * significantly, it again logs information. -- * -- * The monitor also has a unixctl interface. -- * -- * Intended usage in the program's main loop is like this: -- * -- * for (;;) { -- * memory_run(); -- * if (memory_should_report()) { -- * struct simap usage; -- * -- * simap_init(&usage); -- * ...fill in 'usage' with meaningful statistics... -- * memory_report(&usage); -- * simap_destroy(&usage); -- * } -- * -- * ... -- * -- * memory_wait(); -- * poll_block(); -- * } -- */ -- --#include -- --struct simap; -- --void memory_run(void); --void memory_wait(void); -- --bool memory_should_report(void); --void memory_report(const struct simap *usage); -- --#endif /* memory.h */ -Index: openvswitch-2.17.2/lib/netdev-afxdp.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-afxdp.h -+++ /dev/null -@@ -1,87 +0,0 @@ --/* -- * Copyright (c) 2018, 2019 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef NETDEV_AFXDP_H --#define NETDEV_AFXDP_H 1 -- --#ifdef HAVE_AF_XDP -- --#include --#include -- --/* These functions are Linux AF_XDP specific, so they should be used directly -- * only by Linux-specific code. */ -- --enum afxdp_mode { -- OVS_AF_XDP_MODE_UNSPEC, -- OVS_AF_XDP_MODE_BEST_EFFORT, -- OVS_AF_XDP_MODE_NATIVE_ZC, -- OVS_AF_XDP_MODE_NATIVE, -- OVS_AF_XDP_MODE_GENERIC, -- OVS_AF_XDP_MODE_MAX, --}; -- --struct dp_packet; --struct dp_packet_batch; --struct netdev; --struct netdev_afxdp_tx_lock; --struct netdev_custom_stats; --struct netdev_rxq; --struct netdev_stats; --struct smap; --struct xdp_umem; --struct xsk_socket_info; -- --int netdev_afxdp_rxq_construct(struct netdev_rxq *rxq_); --void netdev_afxdp_rxq_destruct(struct netdev_rxq *rxq_); --int netdev_afxdp_init(void); --int netdev_afxdp_construct(struct netdev *netdev_); --void netdev_afxdp_destruct(struct netdev *netdev_); --int netdev_afxdp_verify_mtu_size(const struct netdev *netdev, int mtu); -- --int netdev_afxdp_rxq_recv(struct netdev_rxq *rxq_, -- struct dp_packet_batch *batch, -- int *qfill); --int netdev_afxdp_batch_send(struct netdev *netdev_, int qid, -- struct dp_packet_batch *batch, -- bool concurrent_txq); --int netdev_afxdp_set_config(struct netdev *netdev, const struct smap *args, -- char **errp); --int netdev_afxdp_get_config(const struct netdev *netdev, struct smap *args); --int netdev_afxdp_get_stats(const struct netdev *netdev_, -- struct netdev_stats *stats); --int netdev_afxdp_get_custom_stats(const struct netdev *netdev, -- struct netdev_custom_stats *custom_stats); -- -- --void free_afxdp_buf(struct dp_packet *p); --int netdev_afxdp_reconfigure(struct netdev *netdev); --void signal_remove_xdp(struct netdev *netdev); -- --#else /* !HAVE_AF_XDP */ -- --#include "openvswitch/compiler.h" -- --struct dp_packet; -- --static inline void --free_afxdp_buf(struct dp_packet *p OVS_UNUSED) --{ -- /* Nothing. */ --} -- --#endif /* HAVE_AF_XDP */ --#endif /* netdev-afxdp.h */ -Index: openvswitch-2.17.2/lib/netdev-dpdk.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/netdev-dpdk.h -+++ /dev/null -@@ -1,165 +0,0 @@ --/* -- * Copyright (c) 2014, 2015, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef NETDEV_DPDK_H --#define NETDEV_DPDK_H -- --#include -- --#include "openvswitch/compiler.h" -- --struct dp_packet; --struct netdev; -- --#ifdef DPDK_NETDEV -- --#include -- --void netdev_dpdk_register(void); --void free_dpdk_buf(struct dp_packet *); -- --bool netdev_dpdk_flow_api_supported(struct netdev *); -- --int --netdev_dpdk_rte_flow_destroy(struct netdev *netdev, -- struct rte_flow *rte_flow, -- struct rte_flow_error *error); --struct rte_flow * --netdev_dpdk_rte_flow_create(struct netdev *netdev, -- const struct rte_flow_attr *attr, -- const struct rte_flow_item *items, -- const struct rte_flow_action *actions, -- struct rte_flow_error *error); --int --netdev_dpdk_rte_flow_query_count(struct netdev *netdev, -- struct rte_flow *rte_flow, -- struct rte_flow_query_count *query, -- struct rte_flow_error *error); --int --netdev_dpdk_get_port_id(struct netdev *netdev); -- --#ifdef ALLOW_EXPERIMENTAL_API -- --int netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *, -- struct rte_flow_tunnel *, -- struct rte_flow_action **, -- uint32_t *num_of_actions, -- struct rte_flow_error *); --int netdev_dpdk_rte_flow_tunnel_match(struct netdev *, -- struct rte_flow_tunnel *, -- struct rte_flow_item **, -- uint32_t *num_of_items, -- struct rte_flow_error *); --int netdev_dpdk_rte_flow_get_restore_info(struct netdev *, -- struct dp_packet *, -- struct rte_flow_restore_info *, -- struct rte_flow_error *); --int netdev_dpdk_rte_flow_tunnel_action_decap_release(struct netdev *, -- struct rte_flow_action *, -- uint32_t num_of_actions, -- struct rte_flow_error *); --int netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *, -- struct rte_flow_item *, -- uint32_t num_of_items, -- struct rte_flow_error *); -- --#else -- --static inline void --set_error(struct rte_flow_error *error, enum rte_flow_error_type type) --{ -- if (!error) { -- return; -- } -- error->type = type; -- error->cause = NULL; -- error->message = NULL; --} -- --static inline int --netdev_dpdk_rte_flow_tunnel_decap_set( -- struct netdev *netdev OVS_UNUSED, -- struct rte_flow_tunnel *tunnel OVS_UNUSED, -- struct rte_flow_action **actions OVS_UNUSED, -- uint32_t *num_of_actions OVS_UNUSED, -- struct rte_flow_error *error) --{ -- set_error(error, RTE_FLOW_ERROR_TYPE_ACTION); -- return -1; --} -- --static inline int --netdev_dpdk_rte_flow_tunnel_match(struct netdev *netdev OVS_UNUSED, -- struct rte_flow_tunnel *tunnel OVS_UNUSED, -- struct rte_flow_item **items OVS_UNUSED, -- uint32_t *num_of_items OVS_UNUSED, -- struct rte_flow_error *error) --{ -- set_error(error, RTE_FLOW_ERROR_TYPE_ITEM); -- return -1; --} -- --static inline int --netdev_dpdk_rte_flow_get_restore_info( -- struct netdev *netdev OVS_UNUSED, -- struct dp_packet *p OVS_UNUSED, -- struct rte_flow_restore_info *info OVS_UNUSED, -- struct rte_flow_error *error) --{ -- set_error(error, RTE_FLOW_ERROR_TYPE_ATTR); -- return -1; --} -- --static inline int --netdev_dpdk_rte_flow_tunnel_action_decap_release( -- struct netdev *netdev OVS_UNUSED, -- struct rte_flow_action *actions OVS_UNUSED, -- uint32_t num_of_actions OVS_UNUSED, -- struct rte_flow_error *error) --{ -- set_error(error, RTE_FLOW_ERROR_TYPE_NONE); -- return 0; --} -- --static inline int --netdev_dpdk_rte_flow_tunnel_item_release( -- struct netdev *netdev OVS_UNUSED, -- struct rte_flow_item *items OVS_UNUSED, -- uint32_t num_of_items OVS_UNUSED, -- struct rte_flow_error *error) --{ -- set_error(error, RTE_FLOW_ERROR_TYPE_NONE); -- return 0; --} -- --#endif /* ALLOW_EXPERIMENTAL_API */ -- --#else -- --static inline void --netdev_dpdk_register(void) --{ -- /* Nothing */ --} --static inline void --free_dpdk_buf(struct dp_packet *buf OVS_UNUSED) --{ -- /* Nothing */ --} -- --#endif -- --#endif /* netdev-dpdk.h */ -Index: openvswitch-2.17.2/lib/ovs-atomic-c++.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-c++.h -+++ /dev/null -@@ -1,67 +0,0 @@ --/* This header implements atomic operation primitives on compilers that -- * have built-in support for ++C11 */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#include -- --#define ATOMIC(TYPE) std::atomic -- --using std::atomic_init; -- --using std::memory_order_relaxed; --using std::memory_order_consume; --using std::memory_order_acquire; --using std::memory_order_release; --using std::memory_order_acq_rel; --using std::memory_order_seq_cst; -- --using std::atomic_thread_fence; --using std::atomic_signal_fence; --using std::atomic_is_lock_free; -- --using std::atomic_store; --using std::atomic_store_explicit; -- --using std::atomic_compare_exchange_strong; --using std::atomic_compare_exchange_strong_explicit; --using std::atomic_compare_exchange_weak; --using std::atomic_compare_exchange_weak_explicit; -- --using std::atomic_exchange; --using std::atomic_exchange_explicit; -- --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) --#define atomic_read_explicit(SRC, DST, ORDER) \ -- (*(DST) = std::atomic_load_explicit(SRC, ORDER), \ -- (void) 0) -- --#define atomic_add(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_sub(RMW, ARG, ORIG) \ -- atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_or(RMW, ARG, ORIG) \ -- atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_xor(RMW, ARG, ORIG) \ -- atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_and(RMW, ARG, ORIG) \ -- atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = (*(RMW)).fetch_add(ARG, ORDER), (void) 0) --#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = (*(RMW)).fetch_sub(ARG, ORDER), (void) 0) --#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = (*(RMW)).fetch_or(ARG, ORDER), (void) 0) --#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = (*(RMW)).fetch_xor(ARG, ORDER), (void) 0) --#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = (*(RMW)).fetch_and(ARG, ORDER), (void) 0) -- --using std::atomic_flag; --using std::atomic_flag_test_and_set_explicit; --using std::atomic_flag_test_and_set; --using std::atomic_flag_clear_explicit; --using std::atomic_flag_clear; -Index: openvswitch-2.17.2/lib/ovs-atomic-c11.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-c11.h -+++ /dev/null -@@ -1,54 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives on compilers that -- * have built-in support for C11 */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#include -- --#define OMIT_STANDARD_ATOMIC_TYPES 1 --#define ATOMIC(TYPE) _Atomic(TYPE) -- --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) --#define atomic_read_explicit(SRC, DST, ORDER) \ -- (*(DST) = atomic_load_explicit(SRC, ORDER), \ -- (void) 0) -- --#define atomic_add(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_sub(RMW, ARG, ORIG) \ -- atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_or(RMW, ARG, ORIG) \ -- atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_xor(RMW, ARG, ORIG) \ -- atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) --#define atomic_and(RMW, ARG, ORIG) \ -- atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = atomic_fetch_add_explicit(RMW, ARG, ORDER), (void) 0) --#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = atomic_fetch_sub_explicit(RMW, ARG, ORDER), (void) 0) --#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = atomic_fetch_or_explicit(RMW, ARG, ORDER), (void) 0) --#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = atomic_fetch_xor_explicit(RMW, ARG, ORDER), (void) 0) --#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -- (*(ORIG) = atomic_fetch_and_explicit(RMW, ARG, ORDER), (void) 0) -Index: openvswitch-2.17.2/lib/ovs-atomic-flag-gcc4.7+.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-flag-gcc4.7+.h -+++ /dev/null -@@ -1,52 +0,0 @@ --/* -- * Copyright (c) 2013, 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic_flag on Clang and on GCC 4.7 and later. */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --/* atomic_flag */ -- --typedef struct { -- unsigned char b; --} atomic_flag; --#define ATOMIC_FLAG_INIT { .b = false } -- --static inline bool --atomic_flag_test_and_set_explicit(volatile atomic_flag *object, -- memory_order order) --{ -- return __atomic_test_and_set(&object->b, order); --} -- --static inline bool --atomic_flag_test_and_set(volatile atomic_flag *object) --{ -- return atomic_flag_test_and_set_explicit(object, memory_order_seq_cst); --} -- --static inline void --atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order) --{ -- __atomic_clear(object, order); --} -- --static inline void --atomic_flag_clear(volatile atomic_flag *object) --{ -- atomic_flag_clear_explicit(object, memory_order_seq_cst); --} -Index: openvswitch-2.17.2/lib/ovs-atomic-i586.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-i586.h -+++ /dev/null -@@ -1,489 +0,0 @@ --/* -- * Copyright (c) 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives on 32-bit 586+ with GCC. -- */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#define OVS_ATOMIC_I586_IMPL 1 -- --/* -- * These assumptions have been adopted from the x86_64 Memory model: -- * -- * - 1, 2, and 4 byte loads and stores are atomic on aligned memory. -- * - Loads are not reordered with other loads. -- * - Stores are not reordered with OLDER loads. -- * - Loads may be reordered with OLDER stores to a different memory location, -- * but not with OLDER stores to the same memory location. -- * - Stores are not reordered with other stores, except maybe for special -- * instructions not emitted by compilers, or by the stores performed by -- * a single fast string operation (e.g., "stos"). As long as the atomic -- * stores are not combined with any other stores, even the allowed reordering -- * of the stores by a single fast string operation is not a problem. -- * - Neither loads nor stores are reordered with locked instructions. -- * - Stores by a single processor are observed in the same order by all -- * processors. -- * - (Unlocked) Stores from different processors are NOT ordered. -- * - Memory ordering obeys causality (memory ordering respects transitive -- * visibility). -- * - Any two stores are seen in a consistent order by processors other than -- * the those performing the stores. -- * - Locked instructions have total order. -- * -- * These rules imply that: -- * -- * - Locked instructions are not needed for aligned loads or stores to make -- * them atomic for sizes upto 4 bytes. 8 byte objects need locked -- * instructions. -- * - All stores have release semantics; none of the preceding stores or loads -- * can be reordered with following stores. Following loads could still be -- * reordered to happen before the store, but that is not a violation of the -- * release semantics. -- * - All loads from a given memory location have acquire semantics with -- * respect to the stores on the same memory location; none of the following -- * loads or stores can be reordered with the load. Preceding stores to a -- * different memory location MAY be reordered with the load, but that is not -- * a violation of the acquire semantics (i.e., the loads and stores of two -- * critical sections guarded by a different memory location can overlap). -- * - Locked instructions serve as CPU memory barriers by themselves. -- * - Locked stores implement the sequential consistency memory order. Using -- * locked instructions when seq_cst memory order is requested allows normal -- * loads to observe the stores in the same (total) order without using CPU -- * memory barrier after the loads. -- * -- * NOTE: Some older AMD Opteron processors have a bug that violates the -- * acquire semantics described above. The bug manifests as an unlocked -- * read-modify-write operation following a "semaphore operation" operating -- * on data that existed before entering the critical section; i.e., the -- * preceding "semaphore operation" fails to function as an acquire barrier. -- * The affected CPUs are AMD family 15, models 32 to 63. -- * -- * Ref. http://support.amd.com/TechDocs/25759.pdf errata #147. -- */ -- --/* Barriers. */ -- --#define compiler_barrier() asm volatile(" " : : : "memory") --#define cpu_barrier() asm volatile("lock; addl $0,(%%esp)" ::: "memory", "cc") -- --/* -- * The 'volatile' keyword prevents the compiler from keeping the atomic -- * value in a register, and generates a new memory access for each atomic -- * operation. This allows the implementations of memory_order_relaxed and -- * memory_order_consume to avoid issuing a compiler memory barrier, allowing -- * full optimization of all surrounding non-atomic variables. -- * -- * The placement of the 'volatile' keyword after the 'TYPE' below is highly -- * significant when the TYPE is a pointer type. In that case we want the -- * pointer to be declared volatile, not the data type that is being pointed -- * at! -- * -- * Attribute aligned is used to tell the compiler to align 64-bit data -- * on a 8-byte boundary. This allows more efficient atomic access, as the -- * the CPU guarantees such memory accesses to be atomic. */ --#define ATOMIC(TYPE) TYPE volatile __attribute__((aligned(sizeof(TYPE)))) -- --/* Memory ordering. Must be passed in as a constant. */ --typedef enum { -- memory_order_relaxed, -- memory_order_consume, -- memory_order_acquire, -- memory_order_release, -- memory_order_acq_rel, -- memory_order_seq_cst --} memory_order; -- --#define ATOMIC_BOOL_LOCK_FREE 2 --#define ATOMIC_CHAR_LOCK_FREE 2 --#define ATOMIC_SHORT_LOCK_FREE 2 --#define ATOMIC_INT_LOCK_FREE 2 --#define ATOMIC_LONG_LOCK_FREE 2 --#define ATOMIC_LLONG_LOCK_FREE 2 --#define ATOMIC_POINTER_LOCK_FREE 2 -- --#define IS_LOCKLESS_ATOMIC(OBJECT) \ -- (sizeof(OBJECT) <= 8 && IS_POW2(sizeof(OBJECT))) -- --#define ATOMIC_VAR_INIT(VALUE) VALUE --#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -- --/* -- * The memory_model_relaxed does not need a compiler barrier, if the -- * atomic operation can otherwise be guaranteed to not be moved with -- * respect to other atomic operations on the same memory location. Using -- * the 'volatile' keyword in the definition of the atomic types -- * accomplishes this, as memory accesses to volatile data may not be -- * optimized away, or be reordered with other volatile accesses. -- * -- * On x86 also memory_order_consume is automatic, and data dependency on a -- * volatile atomic variable means that the compiler optimizations should not -- * cause problems. That is, the compiler should not speculate the value of -- * the atomic_read, as it is going to read it from the memory anyway. -- * This allows omiting the compiler memory barrier on atomic_reads with -- * memory_order_consume. This matches the definition of -- * smp_read_barrier_depends() in Linux kernel as a nop for x86, and its usage -- * in rcu_dereference(). -- * -- * We use this same logic below to choose inline assembly statements with or -- * without a compiler memory barrier. -- */ --static inline void --atomic_compiler_barrier(memory_order order) --{ -- if (order > memory_order_consume) { -- compiler_barrier(); -- } --} -- --static inline void --atomic_thread_fence(memory_order order) --{ -- if (order == memory_order_seq_cst) { -- cpu_barrier(); -- } else { -- atomic_compiler_barrier(order); -- } --} -- --static inline void --atomic_signal_fence(memory_order order) --{ -- atomic_compiler_barrier(order); --} -- --#define atomic_is_lock_free(OBJ) \ -- ((void) *(OBJ), \ -- IS_LOCKLESS_ATOMIC(*(OBJ)) ? 2 : 0) -- --/* The 8-byte atomic exchange uses cmpxchg8b with the SRC (ax:dx) as -- * the expected value (bx:cx), which will get replaced by the current -- * value in the likely case it did not match, after which we keep -- * trying until the swap succeeds. */ -- --#if defined(__PIC__) --/* ebx may not be clobbered when compiled with -fPIC, must save and -- * restore it. Furthermore, 'DST' may be addressed via ebx, so the -- * address must be passed via a register so that it remains valid also -- * after changing ebx. */ --#define atomic_exchange_8__(DST, SRC, CLOB) \ -- uint32_t temp____; \ -- \ -- asm volatile(" movl %%ebx,%2 ; " \ -- " movl %%eax,%%ebx ; " \ -- " movl %%edx,%%ecx ; " \ -- "1: " \ -- "lock; cmpxchg8b (%0); " \ -- " jne 1b ; " \ -- " movl %2,%%ebx ; " \ -- " # atomic_exchange_8__ " \ -- : "+r" (DST), /* 0 */ \ -- "+A" (SRC), /* 1 */ \ -- "=mr" (temp____) /* 2 */ \ -- :: "ecx", CLOB, "cc") -- --#else --#define atomic_exchange_8__(DST, SRC, CLOB) \ -- asm volatile(" movl %%eax,%%ebx ; " \ -- " movl %%edx,%%ecx ; " \ -- "1: " \ -- "lock; cmpxchg8b %0 ; " \ -- " jne 1b ; " \ -- " # atomic_exchange_8__ " \ -- : "+m" (*DST), /* 0 */ \ -- "+A" (SRC) /* 1 */ \ -- :: "ebx", "ecx", CLOB, "cc") --#endif -- --#define atomic_exchange__(DST, SRC, ORDER) \ -- ({ \ -- typeof(DST) dst___ = (DST); \ -- typeof(*(DST)) src___ = (SRC); \ -- \ -- if ((ORDER) > memory_order_consume) { \ -- if (sizeof(*(DST)) == 8) { \ -- atomic_exchange_8__(dst___, src___, "memory"); \ -- } else { \ -- asm volatile("xchg %1,%0 ; " \ -- "# atomic_exchange__" \ -- : "+r" (src___), /* 0 */ \ -- "+m" (*dst___) /* 1 */ \ -- :: "memory"); \ -- } \ -- } else { \ -- if (sizeof(*(DST)) == 8) { \ -- atomic_exchange_8__(dst___, src___, "cc"); \ -- } else { \ -- asm volatile("xchg %1,%0 ; " \ -- "# atomic_exchange__" \ -- : "+r" (src___), /* 0 */ \ -- "+m" (*dst___)); /* 1 */ \ -- } \ -- } \ -- src___; \ -- }) -- --#if defined(__SSE__) --/* SSE registers are 128-bit wide, and moving the lowest 64-bits of an SSE -- * register to proerly aligned memory is atomic. See ATOMIC(TYPE) above. */ --#define atomic_store_8__(DST, SRC) \ -- asm volatile("movq %1,%0 ; # atomic_store_8__" \ -- : "=m" (*DST) /* 0 */ \ -- : "x" (SRC)) /* 1, SSE */ --#else --/* Locked 64-bit exchange is available on all i586 CPUs. */ --#define atomic_store_8__(DST, SRC) \ -- atomic_exchange_8__(DST, SRC, "cc") --#endif -- --#define atomic_store_explicit(DST, SRC, ORDER) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(*(DST)) src__ = (SRC); \ -- \ -- if ((ORDER) != memory_order_seq_cst) { \ -- atomic_compiler_barrier(ORDER); \ -- if (sizeof(*(DST)) == 8) { \ -- atomic_store_8__(dst__, src__); \ -- } else { \ -- *dst__ = src__; \ -- } \ -- } else { \ -- atomic_exchange__(dst__, src__, ORDER); \ -- } \ -- (void) 0; \ -- }) --#define atomic_store(DST, SRC) \ -- atomic_store_explicit(DST, SRC, memory_order_seq_cst) -- --#if defined(__SSE__) --/* SSE registers are 128-bit wide, and moving 64-bits from properly aligned -- * memory to an SSE register is atomic. See ATOMIC(TYPE) above. */ --#define atomic_read_8__(SRC, DST) \ -- ({ \ -- typeof(*(DST)) res__; \ -- \ -- asm ("movq %1,%0 ; # atomic_read_8__" \ -- : "=x" (res__) /* 0, SSE. */ \ -- : "m" (*SRC)); /* 1 */ \ -- *(DST) = res__; \ -- }) --#else --/* Must use locked cmpxchg8b (available on all i586 CPUs) if compiled w/o sse -- * support. Compare '*DST' to a random value in bx:cx and returns the actual -- * value in ax:dx. The registers bx and cx are only read, so they are not -- * clobbered. */ --#define atomic_read_8__(SRC, DST) \ -- ({ \ -- typeof(*(DST)) res__; \ -- \ -- asm (" movl %%ebx,%%eax ; " \ -- " movl %%ecx,%%edx ; " \ -- "lock; cmpxchg8b %1 ; " \ -- "# atomic_read_8__ " \ -- : "=&A" (res__), /* 0 */ \ -- "+m" (*SRC) /* 1 */ \ -- : : "cc"); \ -- *(DST) = res__; \ -- }) --#endif -- --#define atomic_read_explicit(SRC, DST, ORDER) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(SRC) src__ = (SRC); \ -- \ -- if (sizeof(*(DST)) <= 4) { \ -- *dst__ = *src__; \ -- } else { \ -- atomic_read_8__(SRC, DST); \ -- } \ -- atomic_compiler_barrier(ORDER); \ -- (void) 0; \ -- }) --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) -- --#if defined(__PIC__) --/* ebx may not be used as an input when compiled with -fPIC, must save -- * and restore it. Furthermore, 'DST' may be addressed via ebx, so -- * the address must be passed via a register so that it remains valid -- * also after changing ebx. */ --#define atomic_compare_exchange_8__(DST, EXP, SRC, RES, CLOB) \ -- asm volatile(" xchgl %%ebx,%3 ; " \ -- "lock; cmpxchg8b (%1) ; " \ -- " xchgl %3,%%ebx ; " \ -- " sete %0 " \ -- "# atomic_compare_exchange_8__" \ -- : "=q" (RES), /* 0 */ \ -- "+r" (DST), /* 1 */ \ -- "+A" (EXP) /* 2 */ \ -- : "r" ((uint32_t)SRC), /* 3 */ \ -- "c" ((uint32_t)((uint64_t)SRC >> 32)) /* 4 */ \ -- : CLOB, "cc") --#else --#define atomic_compare_exchange_8__(DST, EXP, SRC, RES, CLOB) \ -- asm volatile("lock; cmpxchg8b %1 ; " \ -- " sete %0 " \ -- "# atomic_compare_exchange_8__" \ -- : "=q" (RES), /* 0 */ \ -- "+m" (*DST), /* 1 */ \ -- "+A" (EXP) /* 2 */ \ -- : "b" ((uint32_t)SRC), /* 3 */ \ -- "c" ((uint32_t)((uint64_t)SRC >> 32)) /* 4 */ \ -- : CLOB, "cc") --#endif -- --#define atomic_compare_exchange__(DST, EXP, SRC, RES, CLOB) \ -- asm volatile("lock; cmpxchg %3,%1 ; " \ -- " sete %0 " \ -- "# atomic_compare_exchange__" \ -- : "=q" (RES), /* 0 */ \ -- "+m" (*DST), /* 1 */ \ -- "+a" (EXP) /* 2 */ \ -- : "r" (SRC) /* 3 */ \ -- : CLOB, "cc") -- --/* ORD_FAIL is ignored, as atomic_compare_exchange__ already implements -- * at least as strong a barrier as allowed for ORD_FAIL in all cases. */ --#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORDER, ORD_FAIL) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(DST) expp__ = (EXP); \ -- typeof(*(DST)) src__ = (SRC); \ -- typeof(*(DST)) exp__ = *expp__; \ -- uint8_t res__; \ -- (void)ORD_FAIL; \ -- \ -- if ((ORDER) > memory_order_consume) { \ -- if (sizeof(*(DST)) <= 4) { \ -- atomic_compare_exchange__(dst__, exp__, src__, res__, \ -- "memory"); \ -- } else { \ -- atomic_compare_exchange_8__(dst__, exp__, src__, res__, \ -- "memory"); \ -- } \ -- } else { \ -- if (sizeof(*(DST)) <= 4) { \ -- atomic_compare_exchange__(dst__, exp__, src__, res__, \ -- "cc"); \ -- } else { \ -- atomic_compare_exchange_8__(dst__, exp__, src__, res__, \ -- "cc"); \ -- } \ -- } \ -- if (!res__) { \ -- *expp__ = exp__; \ -- } \ -- (bool)res__; \ -- }) --#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -- atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -- memory_order_seq_cst, \ -- memory_order_seq_cst) --#define atomic_compare_exchange_weak \ -- atomic_compare_exchange_strong --#define atomic_compare_exchange_weak_explicit \ -- atomic_compare_exchange_strong_explicit -- --#define atomic_exchange_explicit(RMW, ARG, ORDER) \ -- atomic_exchange__(RMW, ARG, ORDER) --#define atomic_exchange(RMW, ARG) \ -- atomic_exchange_explicit(RMW, ARG, memory_order_seq_cst) -- --#define atomic_add__(RMW, ARG, CLOB) \ -- asm volatile("lock; xadd %0,%1 ; " \ -- "# atomic_add__ " \ -- : "+r" (ARG), /* 0 */ \ -- "+m" (*RMW) /* 1 */ \ -- :: CLOB, "cc") -- --#define atomic_add_32__(RMW, ARG, ORIG, ORDER) \ -- ({ \ -- typeof(RMW) rmw__ = (RMW); \ -- typeof(*(RMW)) arg__ = (ARG); \ -- \ -- if ((ORDER) > memory_order_consume) { \ -- atomic_add__(rmw__, arg__, "memory"); \ -- } else { \ -- atomic_add__(rmw__, arg__, "cc"); \ -- } \ -- *(ORIG) = arg__; \ -- }) -- --/* We could use simple locked instructions if the original value was not -- * needed. */ --#define atomic_op__(RMW, OP, ARG, ORIG, ORDER) \ -- ({ \ -- typeof(RMW) rmw__ = (RMW); \ -- typeof(ARG) arg__ = (ARG); \ -- \ -- typeof(*(RMW)) val__; \ -- \ -- atomic_read_explicit(rmw__, &val__, memory_order_relaxed); \ -- do { \ -- } while (!atomic_compare_exchange_weak_explicit(rmw__, &val__, \ -- val__ OP arg__, \ -- ORDER, \ -- memory_order_relaxed)); \ -- *(ORIG) = val__; \ -- }) -- --#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -- (sizeof(*(RMW)) <= 4 \ -- ? atomic_add_32__(RMW, ARG, ORIG, ORDER) \ -- : atomic_op__(RMW, +, ARG, ORIG, ORDER)) --#define atomic_add(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -- (sizeof(*(RMW)) <= 4 \ -- ? atomic_add_32__(RMW, -(ARG), ORIG, ORDER) \ -- : atomic_op__(RMW, -, ARG, ORIG, ORDER)) --#define atomic_sub(RMW, ARG, ORIG) \ -- atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_op__(RMW, |, ARG, ORIG, ORDER) --#define atomic_or(RMW, ARG, ORIG) \ -- atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_op__(RMW, ^, ARG, ORIG, ORDER) --#define atomic_xor(RMW, ARG, ORIG) \ -- atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_op__(RMW, &, ARG, ORIG, ORDER) --#define atomic_and(RMW, ARG, ORIG) \ -- atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- -- --/* atomic_flag */ -- --typedef ATOMIC(int) atomic_flag; --#define ATOMIC_FLAG_INIT { false } -- --#define atomic_flag_test_and_set_explicit(FLAG, ORDER) \ -- ((bool)atomic_exchange__(FLAG, 1, ORDER)) --#define atomic_flag_test_and_set(FLAG) \ -- atomic_flag_test_and_set_explicit(FLAG, memory_order_seq_cst) -- --#define atomic_flag_clear_explicit(FLAG, ORDER) \ -- atomic_store_explicit(FLAG, 0, ORDER) --#define atomic_flag_clear(FLAG) \ -- atomic_flag_clear_explicit(FLAG, memory_order_seq_cst) -Index: openvswitch-2.17.2/lib/ovs-atomic-locked.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-locked.h -+++ /dev/null -@@ -1,52 +0,0 @@ --/* This header implements atomic operation locking helpers. */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#define OVS_ATOMIC_LOCKED_IMPL 1 -- --void atomic_lock__(void *); --void atomic_unlock__(void *); -- --#define atomic_store_locked(DST, SRC) \ -- (atomic_lock__(DST), \ -- *(DST) = (SRC), \ -- atomic_unlock__(DST), \ -- (void) 0) -- --#define atomic_read_locked(SRC, DST) \ -- (atomic_lock__(SRC), \ -- *(DST) = *(SRC), \ -- atomic_unlock__(SRC), \ -- (void) 0) -- --/* XXX: Evaluates EXP multiple times. */ --#define atomic_compare_exchange_locked(DST, EXP, SRC) \ -- (atomic_lock__(DST), \ -- (*(DST) == *(EXP) \ -- ? (*(DST) = (SRC), \ -- atomic_unlock__(DST), \ -- true) \ -- : (*(EXP) = *(DST), \ -- atomic_unlock__(DST), \ -- false))) -- --#define atomic_exchange_locked(DST, SRC) \ -- ({ \ -- atomic_lock__(DST); \ -- typeof(*(DST)) __tmp = *(DST); \ -- *(DST) = SRC; \ -- atomic_unlock__(DST); \ -- __tmp; \ -- }) -- --#define atomic_op_locked_add += --#define atomic_op_locked_sub -= --#define atomic_op_locked_or |= --#define atomic_op_locked_xor ^= --#define atomic_op_locked_and &= --#define atomic_op_locked(RMW, OP, OPERAND, ORIG) \ -- (atomic_lock__(RMW), \ -- *(ORIG) = *(RMW), \ -- *(RMW) atomic_op_locked_##OP (OPERAND), \ -- atomic_unlock__(RMW)) -Index: openvswitch-2.17.2/lib/ovs-atomic-msvc.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-msvc.h -+++ /dev/null -@@ -1,463 +0,0 @@ --/* -- * Copyright (c) 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives for MSVC -- * on i586 or greater platforms (32 bit). */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --/* From msdn documentation: With Visual Studio 2003, volatile to volatile -- * references are ordered; the compiler will not re-order volatile variable -- * access. With Visual Studio 2005, the compiler also uses acquire semantics -- * for read operations on volatile variables and release semantics for write -- * operations on volatile variables (when supported by the CPU). -- * -- * Though there is no clear documentation that states that anything greater -- * than VS 2005 has the same behavior as described above, looking through MSVCs -- * C++ atomics library in VS2013 shows that the compiler still takes -- * acquire/release semantics on volatile variables. */ --#define ATOMIC(TYPE) TYPE volatile -- --typedef enum { -- memory_order_relaxed, -- memory_order_consume, -- memory_order_acquire, -- memory_order_release, -- memory_order_acq_rel, -- memory_order_seq_cst --} memory_order; -- --#if _MSC_VER > 1800 && defined(_M_IX86) --/* From WDK 10 _InlineInterlocked* functions are renamed to -- * _InlineInterlocked* although the documentation does not specify it */ --#define _InterlockedExchangeAdd64 _InlineInterlockedExchangeAdd64 --#define _InterlockedExchange64 _InlineInterlockedExchange64 --#endif -- --#define ATOMIC_BOOL_LOCK_FREE 2 --#define ATOMIC_CHAR_LOCK_FREE 2 --#define ATOMIC_SHORT_LOCK_FREE 2 --#define ATOMIC_INT_LOCK_FREE 2 --#define ATOMIC_LONG_LOCK_FREE 2 --#define ATOMIC_LLONG_LOCK_FREE 2 --#define ATOMIC_POINTER_LOCK_FREE 2 -- --#define IS_LOCKLESS_ATOMIC(OBJECT) \ -- (sizeof(OBJECT) <= 8 && IS_POW2(sizeof(OBJECT))) -- --#define ATOMIC_VAR_INIT(VALUE) (VALUE) --#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -- --static inline void --atomic_compiler_barrier(memory_order order) --{ -- /* In case of 'memory_order_consume', it is implicitly assumed that -- * the compiler will not move instructions that have data-dependency -- * on the variable in question before the barrier. */ -- if (order > memory_order_consume) { -- _ReadWriteBarrier(); -- } --} -- --static inline void --atomic_thread_fence(memory_order order) --{ -- /* x86 is strongly ordered and acquire/release semantics come -- * automatically. */ -- atomic_compiler_barrier(order); -- if (order == memory_order_seq_cst) { -- MemoryBarrier(); -- atomic_compiler_barrier(order); -- } --} -- --static inline void --atomic_signal_fence(memory_order order) --{ -- atomic_compiler_barrier(order); --} -- --/* 1, 2 and 4 bytes loads and stores are atomic on aligned memory. In addition, -- * since the compiler automatically takes acquire and release semantics on -- * volatile variables, for any order lesser than 'memory_order_seq_cst', we -- * can directly assign or read values. */ -- --#define atomic_store32(DST, SRC, ORDER) \ -- if (ORDER == memory_order_seq_cst) { \ -- InterlockedExchange((long volatile *) (DST), \ -- (long) (SRC)); \ -- } else { \ -- *(DST) = (SRC); \ -- } -- --/* MSVC converts 64 bit writes into two instructions. So there is -- * a possibility that an interrupt can make a 64 bit write non-atomic even -- * when 8 byte aligned. So use InterlockedExchange64(). -- * -- * For atomic stores, 'consume' and 'acquire' semantics are not valid. But we -- * are using 'Exchange' to get atomic stores here and we only have -- * InterlockedExchange64(), InterlockedExchangeNoFence64() and -- * InterlockedExchange64Acquire() available. So we are forced to use -- * InterlockedExchange64() which uses full memory barrier for everything -- * greater than 'memory_order_relaxed'. */ --#ifdef _M_IX86 --#define atomic_store64(DST, SRC, ORDER) \ -- if (ORDER == memory_order_relaxed) { \ -- InterlockedExchangeNoFence64((int64_t volatile *) (DST), \ -- (int64_t) (SRC)); \ -- } else { \ -- InterlockedExchange64((int64_t volatile *) (DST), (int64_t) (SRC));\ -- } --#elif _M_X64 --/* 64 bit writes are atomic on amd64 if 64 bit aligned. */ --#define atomic_store64(DST, SRC, ORDER) \ -- if (ORDER == memory_order_seq_cst) { \ -- InterlockedExchange64((int64_t volatile *) (DST), \ -- (int64_t) (SRC)); \ -- } else { \ -- *(DST) = (SRC); \ -- } --#endif -- --#define atomic_store8(DST, SRC, ORDER) \ -- if (ORDER == memory_order_seq_cst) { \ -- InterlockedExchange8((char volatile *) (DST), (char) (SRC)); \ -- } else { \ -- *(DST) = (SRC); \ -- } -- --#define atomic_store16(DST, SRC, ORDER) \ -- if (ORDER == memory_order_seq_cst) { \ -- InterlockedExchange16((short volatile *) (DST), (short) (SRC)); \ -- } else { \ -- *(DST) = (SRC); \ -- } -- --#define atomic_store(DST, SRC) \ -- atomic_store_explicit(DST, SRC, memory_order_seq_cst) -- --#define atomic_store_explicit(DST, SRC, ORDER) \ -- if (sizeof *(DST) == 1) { \ -- atomic_store8(DST, SRC, ORDER) \ -- } else if (sizeof *(DST) == 2) { \ -- atomic_store16( DST, SRC, ORDER) \ -- } else if (sizeof *(DST) == 4) { \ -- atomic_store32(DST, SRC, ORDER) \ -- } else if (sizeof *(DST) == 8) { \ -- atomic_store64(DST, SRC, ORDER) \ -- } else { \ -- abort(); \ -- } -- --/* On x86, for 'memory_order_seq_cst', if stores are locked, the corresponding -- * reads don't need to be locked (based on the following in Intel Developers -- * manual: -- * “Locked operations are atomic with respect to all other memory operations -- * and all externally visible events. Only instruction fetch and page table -- * accesses can pass locked instructions. Locked instructions can be used to -- * synchronize data written by one processor and read by another processor. -- * For the P6 family processors, locked operations serialize all outstanding -- * load and store operations (that is, wait for them to complete). This rule -- * is also true for the Pentium 4 and Intel Xeon processors, with one -- * exception. Load operations that reference weakly ordered memory types -- * (such as the WC memory type) may not be serialized."). */ -- -- /* For 8, 16 and 32 bit variations. */ --#define atomic_readX(SRC, DST, ORDER) \ -- *(DST) = *(SRC); -- --/* MSVC converts 64 bit reads into two instructions. So there is -- * a possibility that an interrupt can make a 64 bit read non-atomic even -- * when 8 byte aligned. So use fully memory barrier InterlockedOr64(). */ --#ifdef _M_IX86 --#define atomic_read64(SRC, DST, ORDER) \ -- __pragma (warning(push)) \ -- __pragma (warning(disable:4047)) \ -- *(DST) = InterlockedOr64((int64_t volatile *) (SRC), 0); \ -- __pragma (warning(pop)) --#elif _M_X64 --/* 64 bit reads are atomic on amd64 if 64 bit aligned. */ --#define atomic_read64(SRC, DST, ORDER) \ -- *(DST) = *(SRC); --#endif -- --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) -- --#define atomic_read_explicit(SRC, DST, ORDER) \ -- if (sizeof *(DST) == 1 || sizeof *(DST) == 2 || sizeof *(DST) == 4) { \ -- atomic_readX(SRC, DST, ORDER) \ -- } else if (sizeof *(DST) == 8) { \ -- atomic_read64(SRC, DST, ORDER) \ -- } else { \ -- abort(); \ -- } -- --/* For add, sub, and logical operations, for 8, 16 and 64 bit data types, -- * functions for all the different memory orders does not exist -- * (though documentation exists for some of them). The MSVC C++ library which -- * implements the c11 atomics simply calls the full memory barrier function -- * for everything in x86(see xatomic.h). So do the same here. */ -- --/* For 8, 16 and 64 bit variations. */ --#define atomic_op(OP, X, RMW, ARG, ORIG, ORDER) \ -- atomic_##OP##_generic(X, RMW, ARG, ORIG, ORDER) -- --/* Arithmetic addition calls. */ -- --#define atomic_add8(RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = _InterlockedExchangeAdd8((char volatile *) (RMW), \ -- (char) (ARG)); -- --#define atomic_add16(RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = _InterlockedExchangeAdd16((short volatile *) (RMW), \ -- (short) (ARG)); -- --#define atomic_add32(RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = InterlockedExchangeAdd((long volatile *) (RMW), \ -- (long) (ARG)); --#define atomic_add64(RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = _InterlockedExchangeAdd64((int64_t volatile *) (RMW), \ -- (int64_t) (ARG)); -- --#define atomic_add(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -- if (sizeof *(RMW) == 1) { \ -- atomic_add8(RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 2) { \ -- atomic_add16(RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 4) { \ -- atomic_add32(RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 8) { \ -- atomic_add64(RMW, ARG, ORIG, ORDER) \ -- } else { \ -- abort(); \ -- } -- --/* Arithmetic subtraction calls. */ -- --#define atomic_sub(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, (0 - (ARG)), ORIG, memory_order_seq_cst) -- --#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_add_explicit(RMW, (0 - (ARG)), ORIG, ORDER) -- --/* Logical 'and' calls. */ -- --#define atomic_and32(RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = InterlockedAnd((int32_t volatile *) (RMW), (int32_t) (ARG)); -- --/* For 8, 16 and 64 bit variations. */ --#define atomic_and_generic(X, RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = InterlockedAnd##X((int##X##_t volatile *) (RMW), \ -- (int##X##_t) (ARG)); -- --#define atomic_and(RMW, ARG, ORIG) \ -- atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -- if (sizeof *(RMW) == 1) { \ -- atomic_op(and, 8, RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 2) { \ -- atomic_op(and, 16, RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 4) { \ -- atomic_and32(RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 8) { \ -- atomic_op(and, 64, RMW, ARG, ORIG, ORDER) \ -- } else { \ -- abort(); \ -- } -- --/* Logical 'Or' calls. */ -- --#define atomic_or32(RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = InterlockedOr((int32_t volatile *) (RMW), (int32_t) (ARG)); -- --/* For 8, 16 and 64 bit variations. */ --#define atomic_or_generic(X, RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = InterlockedOr##X((int##X##_t volatile *) (RMW), \ -- (int##X##_t) (ARG)); -- --#define atomic_or(RMW, ARG, ORIG) \ -- atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -- if (sizeof *(RMW) == 1) { \ -- atomic_op(or, 8, RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 2) { \ -- atomic_op(or, 16, RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 4) { \ -- atomic_or32(RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 8) { \ -- atomic_op(or, 64, RMW, ARG, ORIG, ORDER) \ -- } else { \ -- abort(); \ -- } -- --/* Logical Xor calls. */ -- --#define atomic_xor32(RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = InterlockedXor((int32_t volatile *) (RMW), (int32_t) (ARG)); -- --/* For 8, 16 and 64 bit variations. */ --#define atomic_xor_generic(X, RMW, ARG, ORIG, ORDER) \ -- *(ORIG) = InterlockedXor##X((int##X##_t volatile *) (RMW), \ -- (int##X##_t) (ARG)); -- --#define atomic_xor(RMW, ARG, ORIG) \ -- atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -- if (sizeof *(RMW) == 1) { \ -- atomic_op(xor, 8, RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 2) { \ -- atomic_op(xor, 16, RMW, ARG, ORIG, ORDER) \ -- } else if (sizeof *(RMW) == 4) { \ -- atomic_xor32(RMW, ARG, ORIG, ORDER); \ -- } else if (sizeof *(RMW) == 8) { \ -- atomic_op(xor, 64, RMW, ARG, ORIG, ORDER) \ -- } else { \ -- abort(); \ -- } -- --#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -- atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -- memory_order_seq_cst, \ -- memory_order_seq_cst) -- --#define atomic_compare_exchange_weak atomic_compare_exchange_strong --#define atomic_compare_exchange_weak_explicit \ -- atomic_compare_exchange_strong_explicit -- --/* While intrinsics offering different memory ordering -- * are available in MSVC C compiler, they are not defined -- * in the C++ compiler. Ignore for compatibility. -- * -- * Use nested ternary operators as the GNU extension ({}) -- * is not available. -- */ -- --#define atomic_exchange_explicit(DST, SRC, ORDER) \ -- ((sizeof *(DST) == 1) ? \ -- _InterlockedExchange8((char volatile *) DST, SRC) \ -- : (sizeof *(DST) == 2) ? \ -- _InterlockedExchange16((short volatile *) DST, SRC) \ -- : (sizeof *(DST) == 4) ? \ -- _InterlockedExchange((long int volatile *) DST, SRC) \ -- : (sizeof *(DST) == 8) ? \ -- _InterlockedExchange64((__int64 volatile *) DST, SRC) \ -- : (abort(), 0)) -- --#define atomic_exchange(DST, SRC) \ -- atomic_exchange_explicit(DST, SRC, memory_order_seq_cst) -- --/* MSVCs c++ compiler implements c11 atomics and looking through its -- * implementation (in xatomic.h), orders are ignored for x86 platform. -- * Do the same here. */ --static inline bool --atomic_compare_exchange8(int8_t volatile *dst, int8_t *expected, int8_t src) --{ -- int8_t previous = _InterlockedCompareExchange8((char volatile *)dst, -- src, *expected); -- if (previous == *expected) { -- return true; -- } else { -- *expected = previous; -- return false; -- } --} -- --static inline bool --atomic_compare_exchange16(int16_t volatile *dst, int16_t *expected, -- int16_t src) --{ -- int16_t previous = InterlockedCompareExchange16(dst, src, *expected); -- if (previous == *expected) { -- return true; -- } else { -- *expected = previous; -- return false; -- } --} -- --static inline bool --atomic_compare_exchange32(int32_t volatile *dst, int32_t *expected, -- int32_t src) --{ -- int32_t previous = InterlockedCompareExchange((long volatile *)dst, -- src, *expected); -- if (previous == *expected) { -- return true; -- } else { -- *expected = previous; -- return false; -- } --} -- --static inline bool --atomic_compare_exchange64(int64_t volatile *dst, int64_t *expected, -- int64_t src) --{ -- int64_t previous = InterlockedCompareExchange64(dst, src, *expected); -- if (previous == *expected) { -- return true; -- } else { -- *expected = previous; -- return false; -- } --} -- --static inline bool --atomic_compare_unreachable() --{ -- return true; --} -- --#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORD1, ORD2) \ -- (sizeof *(DST) == 1 \ -- ? atomic_compare_exchange8((int8_t volatile *) (DST), (int8_t *) (EXP), \ -- (int8_t) (SRC)) \ -- : (sizeof *(DST) == 2 \ -- ? atomic_compare_exchange16((int16_t volatile *) (DST), \ -- (int16_t *) (EXP), (int16_t) (SRC)) \ -- : (sizeof *(DST) == 4 \ -- ? atomic_compare_exchange32((int32_t volatile *) (DST), \ -- (int32_t *) (EXP), (int32_t) (SRC)) \ -- : (sizeof *(DST) == 8 \ -- ? atomic_compare_exchange64((int64_t volatile *) (DST), \ -- (int64_t *) (EXP), (int64_t) (SRC)) \ -- : ovs_fatal(0, "atomic operation with size greater than 8 bytes"), \ -- atomic_compare_unreachable())))) -- -- --/* atomic_flag */ -- --typedef ATOMIC(int32_t) atomic_flag; --#define ATOMIC_FLAG_INIT 0 -- --#define atomic_flag_test_and_set(FLAG) \ -- (bool) InterlockedBitTestAndSet(FLAG, 0) -- --#define atomic_flag_test_and_set_explicit(FLAG, ORDER) \ -- atomic_flag_test_and_set(FLAG) -- --#define atomic_flag_clear_explicit(FLAG, ORDER) \ -- atomic_flag_clear() --#define atomic_flag_clear(FLAG) \ -- InterlockedBitTestAndReset(FLAG, 0) -Index: openvswitch-2.17.2/lib/ovs-atomic-x86_64.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/ovs-atomic-x86_64.h -+++ /dev/null -@@ -1,356 +0,0 @@ --/* -- * Copyright (c) 2014 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --/* This header implements atomic operation primitives on x86_64 with GCC. */ --#ifndef IN_OVS_ATOMIC_H --#error "This header should only be included indirectly via ovs-atomic.h." --#endif -- --#define OVS_ATOMIC_X86_64_IMPL 1 -- --/* -- * x86_64 Memory model (http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html): -- * -- * - 1, 2, 4, and 8 byte loads and stores are atomic on aligned memory. -- * - Loads are not reordered with other loads. -- * - Stores are not reordered with OLDER loads. -- * - Loads may be reordered with OLDER stores to a different memory location, -- * but not with OLDER stores to the same memory location. -- * - Stores are not reordered with other stores, except for special -- * instructions (CLFLUSH, streaming stores, fast string operations). -- * Most of these are not emitted by compilers, and as long as the -- * atomic stores are not combined with any other stores, even the allowed -- * reordering of the stores by a single fast string operation (e.g., "stos") -- * is not a problem. -- * - Neither loads nor stores are reordered with locked instructions. -- * - Loads cannot pass earlier LFENCE or MFENCE instructions. -- * - Stores cannot pass earlier LFENCE, SFENCE, or MFENCE instructions. -- * - LFENCE instruction cannot pass earlier loads. -- * - SFENCE instruction cannot pass earlier stores. -- * - MFENCE instruction cannot pass earlier loads or stores. -- * - Stores by a single processor are observed in the same order by all -- * processors. -- * - (Unlocked) Stores from different processors are NOT ordered. -- * - Memory ordering obeys causality (memory ordering respects transitive -- * visibility). -- * - Any two stores are seen in a consistent order by processors other than -- * the those performing the stores. -- * - Locked instructions have total order. -- * -- * These rules imply that: -- * -- * - Locked instructions are not needed for aligned loads or stores to make -- * them atomic. -- * - All stores have release semantics; none of the preceding stores or loads -- * can be reordered with following stores. Following loads could still be -- * reordered to happen before the store, but that is not a violation of the -- * release semantics. -- * - All loads from a given memory location have acquire semantics with -- * respect to the stores on the same memory location; none of the following -- * loads or stores can be reordered with the load. Preceding stores to a -- * different memory location MAY be reordered with the load, but that is not -- * a violation of the acquire semantics (i.e., the loads and stores of two -- * critical sections guarded by a different memory location can overlap). -- * - Locked instructions serve as CPU memory barriers by themselves. -- * - Locked stores implement the sequential consistency memory order. Using -- * locked instructions when seq_cst memory order is requested allows normal -- * loads to observe the stores in the same (total) order without using CPU -- * memory barrier after the loads. -- * -- * NOTE: Some older AMD Opteron processors have a bug that violates the -- * acquire semantics described above. The bug manifests as an unlocked -- * read-modify-write operation following a "semaphore operation" operating -- * on data that existed before entering the critical section; i.e., the -- * preceding "semaphore operation" fails to function as an acquire barrier. -- * The affected CPUs are AMD family 15, models 32 to 63. -- * -- * Ref. http://support.amd.com/TechDocs/25759.pdf errata #147. -- */ -- --/* Barriers. */ -- --#define compiler_barrier() asm volatile(" " : : : "memory") --#define cpu_barrier() asm volatile("mfence;" : : : "memory") -- --/* -- * The 'volatile' keyword prevents the compiler from keeping the atomic -- * value in a register, and generates a new memory access for each atomic -- * operation. This allows the implementations of memory_order_relaxed and -- * memory_order_consume to avoid issuing a compiler memory barrier, allowing -- * full optimization of all surrounding non-atomic variables. -- * -- * The placement of the 'volatile' keyword after the 'TYPE' below is highly -- * significant when the TYPE is a pointer type. In that case we want the -- * pointer to be declared volatile, not the data type that is being pointed -- * at! -- */ --#define ATOMIC(TYPE) TYPE volatile -- --/* Memory ordering. Must be passed in as a constant. */ --typedef enum { -- memory_order_relaxed, -- memory_order_consume, -- memory_order_acquire, -- memory_order_release, -- memory_order_acq_rel, -- memory_order_seq_cst --} memory_order; -- --#define ATOMIC_BOOL_LOCK_FREE 2 --#define ATOMIC_CHAR_LOCK_FREE 2 --#define ATOMIC_SHORT_LOCK_FREE 2 --#define ATOMIC_INT_LOCK_FREE 2 --#define ATOMIC_LONG_LOCK_FREE 2 --#define ATOMIC_LLONG_LOCK_FREE 2 --#define ATOMIC_POINTER_LOCK_FREE 2 -- --#define IS_LOCKLESS_ATOMIC(OBJECT) \ -- (sizeof(OBJECT) <= 8 && IS_POW2(sizeof(OBJECT))) -- --#define ATOMIC_VAR_INIT(VALUE) VALUE --#define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0) -- --/* -- * The memory_model_relaxed does not need a compiler barrier, if the -- * atomic operation can otherwise be guaranteed to not be moved with -- * respect to other atomic operations on the same memory location. Using -- * the 'volatile' keyword in the definition of the atomic types -- * accomplishes this, as memory accesses to volatile data may not be -- * optimized away, or be reordered with other volatile accesses. -- * -- * On x86 also memory_order_consume is automatic, and data dependency on a -- * volatile atomic variable means that the compiler optimizations should not -- * cause problems. That is, the compiler should not speculate the value of -- * the atomic_read, as it is going to read it from the memory anyway. -- * This allows omiting the compiler memory barrier on atomic_reads with -- * memory_order_consume. This matches the definition of -- * smp_read_barrier_depends() in Linux kernel as a nop for x86, and its usage -- * in rcu_dereference(). -- * -- * We use this same logic below to choose inline assembly statements with or -- * without a compiler memory barrier. -- */ --static inline void --atomic_compiler_barrier(memory_order order) --{ -- if (order > memory_order_consume) { -- compiler_barrier(); -- } --} -- --static inline void --atomic_thread_fence(memory_order order) --{ -- if (order == memory_order_seq_cst) { -- cpu_barrier(); -- } else { -- atomic_compiler_barrier(order); -- } --} -- --static inline void --atomic_signal_fence(memory_order order) --{ -- atomic_compiler_barrier(order); --} -- --#define atomic_is_lock_free(OBJ) \ -- ((void) *(OBJ), \ -- IS_LOCKLESS_ATOMIC(*(OBJ)) ? 2 : 0) -- --#define atomic_exchange__(DST, SRC, ORDER) \ -- ({ \ -- typeof(DST) dst___ = (DST); \ -- typeof(*(DST)) src___ = (SRC); \ -- \ -- if ((ORDER) > memory_order_consume) { \ -- asm volatile("xchg %1,%0 ; " \ -- "# atomic_exchange__" \ -- : "+r" (src___), /* 0 */ \ -- "+m" (*dst___) /* 1 */ \ -- :: "memory"); \ -- } else { \ -- asm volatile("xchg %1,%0 ; " \ -- "# atomic_exchange__" \ -- : "+r" (src___), /* 0 */ \ -- "+m" (*dst___)); /* 1 */ \ -- } \ -- src___; \ -- }) -- --/* Atomic store: Valid memory models are: -- * -- * memory_order_relaxed, memory_order_release, and -- * memory_order_seq_cst. */ --#define atomic_store_explicit(DST, SRC, ORDER) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(*(DST)) src__ = (SRC); \ -- \ -- if ((ORDER) != memory_order_seq_cst) { \ -- atomic_compiler_barrier(ORDER); \ -- *dst__ = src__; \ -- } else { \ -- atomic_exchange__(dst__, src__, ORDER); \ -- } \ -- (void) 0; \ -- }) --#define atomic_store(DST, SRC) \ -- atomic_store_explicit(DST, SRC, memory_order_seq_cst) -- --/* Atomic read: Valid memory models are: -- * -- * memory_order_relaxed, memory_order_consume, memory_model_acquire, -- * and memory_order_seq_cst. */ --#define atomic_read_explicit(SRC, DST, ORDER) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(SRC) src__ = (SRC); \ -- \ -- *dst__ = *src__; \ -- atomic_compiler_barrier(ORDER); \ -- (void) 0; \ -- }) --#define atomic_read(SRC, DST) \ -- atomic_read_explicit(SRC, DST, memory_order_seq_cst) -- --#define atomic_compare_exchange__(DST, EXP, SRC, RES, CLOB) \ -- asm volatile("lock; cmpxchg %3,%1 ; " \ -- " sete %0 " \ -- "# atomic_compare_exchange__" \ -- : "=q" (RES), /* 0 */ \ -- "+m" (*DST), /* 1 */ \ -- "+a" (EXP) /* 2 */ \ -- : "r" (SRC) /* 3 */ \ -- : CLOB, "cc") -- --/* All memory models are valid for read-modify-write operations. -- * -- * Valid memory models for the read operation of the current value in -- * the failure case are the same as for atomic read, but can not be -- * stronger than the success memory model. -- * ORD_FAIL is ignored, as atomic_compare_exchange__ already implements -- * at least as strong a barrier as allowed for ORD_FAIL in all cases. */ --#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORDER, ORD_FAIL) \ -- ({ \ -- typeof(DST) dst__ = (DST); \ -- typeof(DST) expp__ = (EXP); \ -- typeof(*(DST)) src__ = (SRC); \ -- typeof(*(DST)) exp__ = *expp__; \ -- uint8_t res__; \ -- (void)ORD_FAIL; \ -- \ -- if ((ORDER) > memory_order_consume) { \ -- atomic_compare_exchange__(dst__, exp__, src__, res__, \ -- "memory"); \ -- } else { \ -- atomic_compare_exchange__(dst__, exp__, src__, res__, \ -- "cc"); \ -- } \ -- if (!res__) { \ -- *expp__ = exp__; \ -- } \ -- (bool)res__; \ -- }) --#define atomic_compare_exchange_strong(DST, EXP, SRC) \ -- atomic_compare_exchange_strong_explicit(DST, EXP, SRC, \ -- memory_order_seq_cst, \ -- memory_order_seq_cst) --#define atomic_compare_exchange_weak \ -- atomic_compare_exchange_strong --#define atomic_compare_exchange_weak_explicit \ -- atomic_compare_exchange_strong_explicit -- --#define atomic_exchange_explicit(RMW, ARG, ORDER) \ -- atomic_exchange__(RMW, ARG, ORDER) --#define atomic_exchange(RMW, ARG) \ -- atomic_exchange_explicit(RMW, ARG, memory_order_seq_cst) -- --#define atomic_add__(RMW, ARG, CLOB) \ -- asm volatile("lock; xadd %0,%1 ; " \ -- "# atomic_add__ " \ -- : "+r" (ARG), /* 0 */ \ -- "+m" (*RMW) /* 1 */ \ -- :: CLOB, "cc") -- --#define atomic_add_explicit(RMW, ARG, ORIG, ORDER) \ -- ({ \ -- typeof(RMW) rmw__ = (RMW); \ -- typeof(*(RMW)) arg__ = (ARG); \ -- \ -- if ((ORDER) > memory_order_consume) { \ -- atomic_add__(rmw__, arg__, "memory"); \ -- } else { \ -- atomic_add__(rmw__, arg__, "cc"); \ -- } \ -- *(ORIG) = arg__; \ -- }) --#define atomic_add(RMW, ARG, ORIG) \ -- atomic_add_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_sub_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_add_explicit(RMW, -(ARG), ORIG, ORDER) --#define atomic_sub(RMW, ARG, ORIG) \ -- atomic_sub_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --/* We could use simple locked instructions if the original value was not -- * needed. */ --#define atomic_op__(RMW, OP, ARG, ORIG, ORDER) \ -- ({ \ -- typeof(RMW) rmw__ = (RMW); \ -- typeof(ARG) arg__ = (ARG); \ -- \ -- typeof(*(RMW)) val__; \ -- \ -- atomic_read_explicit(rmw__, &val__, memory_order_relaxed); \ -- do { \ -- } while (!atomic_compare_exchange_weak_explicit(rmw__, &val__, \ -- val__ OP arg__, \ -- ORDER, \ -- memory_order_relaxed)); \ -- *(ORIG) = val__; \ -- }) -- --#define atomic_or_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_op__(RMW, |, ARG, ORIG, ORDER) --#define atomic_or(RMW, ARG, ORIG) \ -- atomic_or_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_xor_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_op__(RMW, ^, ARG, ORIG, ORDER) --#define atomic_xor(RMW, ARG, ORIG) \ -- atomic_xor_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- --#define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \ -- atomic_op__(RMW, &, ARG, ORIG, ORDER) --#define atomic_and(RMW, ARG, ORIG) \ -- atomic_and_explicit(RMW, ARG, ORIG, memory_order_seq_cst) -- -- --/* atomic_flag */ -- --typedef ATOMIC(int) atomic_flag; --#define ATOMIC_FLAG_INIT { false } -- --#define atomic_flag_test_and_set_explicit(FLAG, ORDER) \ -- ((bool)atomic_exchange__(FLAG, 1, ORDER)) --#define atomic_flag_test_and_set(FLAG) \ -- atomic_flag_test_and_set_explicit(FLAG, memory_order_seq_cst) -- --#define atomic_flag_clear_explicit(FLAG, ORDER) \ -- atomic_store_explicit(FLAG, 0, ORDER) --#define atomic_flag_clear(FLAG) \ -- atomic_flag_clear_explicit(FLAG, memory_order_seq_cst) -Index: openvswitch-2.17.2/lib/process.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/process.h -+++ /dev/null -@@ -1,61 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2011, 2013 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef PROCESS_H --#define PROCESS_H 1 -- --#include --#include -- --struct process; -- --struct process_info { -- unsigned long int vsz; /* Virtual size, in kB. */ -- unsigned long int rss; /* Resident set size, in kB. */ -- long long int booted; /* ms since monitor started. */ -- int crashes; /* # of crashes (usually 0). */ -- long long int uptime; /* ms since last (re)started by monitor. */ -- long long int cputime; /* ms of CPU used during 'uptime'. */ -- int core_id; -- char name[18]; --}; -- --/* Starting and monitoring subprocesses. -- * -- * process_init() and process_start() may safely be called only from a -- * single-threaded parent process. The parent process may safely create -- * additional threads afterward, as long as the remaining functions in this -- * group are called only from a single thread at any given time. */ --void process_init(void); --int process_start(char **argv, struct process **); --void process_destroy(struct process *); --int process_kill(const struct process *, int signr); --pid_t process_pid(const struct process *); --const char *process_name(const struct process *); --bool process_exited(struct process *); --int process_status(const struct process *); --void process_run(void); --void process_wait(struct process *); -- --int count_crashes(pid_t); --bool get_process_info(pid_t, struct process_info *); -- --/* These functions are thread-safe. */ --char *process_status_msg(int); --char *process_escape_args(char **argv); --char *process_search_path(const char *); -- --#endif /* process.h */ -Index: openvswitch-2.17.2/lib/random.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/random.h -+++ /dev/null -@@ -1,48 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2012 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef RANDOM_H --#define RANDOM_H 1 -- --#include --#include -- --void random_init(void); --void random_set_seed(uint32_t); -- --void random_bytes(void *, size_t); --uint32_t random_uint32(void); --uint64_t random_uint64(void); -- --static inline int --random_range(int max) --{ -- return random_uint32() % max; --} -- --static inline uint8_t --random_uint8(void) --{ -- return random_uint32(); --} -- --static inline uint16_t --random_uint16(void) --{ -- return random_uint32(); --} -- --#endif /* random.h */ -Index: openvswitch-2.17.2/lib/simap.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/simap.h -+++ /dev/null -@@ -1,89 +0,0 @@ --/* -- * Copyright (c) 2009, 2010, 2011, 2012, 2016, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef SIMAP_H --#define SIMAP_H 1 -- --#include "openvswitch/hmap.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --/* A map from strings to unsigned integers. */ --struct simap { -- struct hmap map; /* Contains "struct simap_node"s. */ --}; -- --struct simap_node { -- struct hmap_node node; /* In struct simap's 'map' hmap. */ -- char *name; -- unsigned int data; --}; -- --#define SIMAP_INITIALIZER(SIMAP) { HMAP_INITIALIZER(&(SIMAP)->map) } -- --#define SIMAP_FOR_EACH(SIMAP_NODE, SIMAP) \ -- HMAP_FOR_EACH_INIT (SIMAP_NODE, node, &(SIMAP)->map, \ -- BUILD_ASSERT_TYPE(SIMAP_NODE, struct simap_node *), \ -- BUILD_ASSERT_TYPE(SIMAP, struct simap *)) -- --#define SIMAP_FOR_EACH_SAFE_SHORT(SIMAP_NODE, SIMAP) \ -- HMAP_FOR_EACH_SAFE_SHORT_INIT (SIMAP_NODE, node, &(SIMAP)->map, \ -- BUILD_ASSERT_TYPE(SIMAP_NODE, struct simap_node *), \ -- BUILD_ASSERT_TYPE(SIMAP, struct simap *)) -- --#define SIMAP_FOR_EACH_SAFE_LONG(SIMAP_NODE, NEXT, SIMAP) \ -- HMAP_FOR_EACH_SAFE_LONG_INIT (SIMAP_NODE, NEXT, node, &(SIMAP)->map, \ -- BUILD_ASSERT_TYPE(SIMAP_NODE, struct simap_node *), \ -- BUILD_ASSERT_TYPE(NEXT, struct simap_node *), \ -- BUILD_ASSERT_TYPE(SIMAP, struct simap *)) -- --#define SIMAP_FOR_EACH_SAFE(...) \ -- OVERLOAD_SAFE_MACRO(SIMAP_FOR_EACH_SAFE_LONG, \ -- SIMAP_FOR_EACH_SAFE_SHORT, \ -- 3, __VA_ARGS__) -- --void simap_init(struct simap *); --void simap_destroy(struct simap *); --void simap_swap(struct simap *, struct simap *); --void simap_moved(struct simap *); --void simap_clear(struct simap *); -- --bool simap_is_empty(const struct simap *); --size_t simap_count(const struct simap *); -- --bool simap_put(struct simap *, const char *, unsigned int); --unsigned int simap_increase(struct simap *, const char *, unsigned int); -- --unsigned int simap_get(const struct simap *, const char *); --struct simap_node *simap_find(const struct simap *, const char *); --struct simap_node *simap_find_len(const struct simap *, -- const char *, size_t len); --bool simap_contains(const struct simap *, const char *); -- --void simap_delete(struct simap *, struct simap_node *); --bool simap_find_and_delete(struct simap *, const char *); -- --const struct simap_node **simap_sort(const struct simap *); --bool simap_equal(const struct simap *, const struct simap *); --uint32_t simap_hash(const struct simap *); -- --#ifdef __cplusplus --} --#endif -- --#endif /* simap.h */ -Index: openvswitch-2.17.2/lib/skiplist.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/skiplist.h -+++ /dev/null -@@ -1,49 +0,0 @@ --/* Copyright (C) 2016 Hewlett Packard Enterprise Development LP -- * All Rights Reserved. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); you may -- * not use this file except in compliance with the License. You may obtain -- * a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -- * License for the specific language governing permissions and limitations -- * under the License. -- */ -- --#ifndef LIB_SKIPLIST_H_ --#define LIB_SKIPLIST_H_ -- --#include --#include --#include -- --typedef int (skiplist_comparator)(const void *a, const void *b, -- const void *conf); -- --struct skiplist_node; -- --struct skiplist; -- --#define SKIPLIST_FOR_EACH (SKIPLIST_NODE, SKIPLIST) \ -- for (SKIPLIST_NODE = skiplist_first(SKIPLIST); \ -- SKIPLIST_NODE; \ -- SKIPLIST_NODE = skiplist_next(SKIPLIST_NODE)) -- --struct skiplist *skiplist_create(skiplist_comparator *object_comparator, -- void *configuration); --void skiplist_insert(struct skiplist *sl, const void *object); --void *skiplist_delete(struct skiplist *sl, const void *object); --struct skiplist_node *skiplist_find(struct skiplist *sl, const void *value); --void *skiplist_get_data(struct skiplist_node *node); --uint32_t skiplist_get_size(struct skiplist *sl); --struct skiplist_node *skiplist_forward_to(struct skiplist *sl, -- const void *value); --struct skiplist_node *skiplist_first(struct skiplist *sl); --struct skiplist_node *skiplist_next(struct skiplist_node *node); --void skiplist_destroy(struct skiplist *sl, void (*func)(void *)); -- --#endif /* LIB_SKIPLIST_H_ */ -Index: openvswitch-2.17.2/lib/socket-util.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/socket-util.h -+++ /dev/null -@@ -1,185 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef SOCKET_UTIL_H --#define SOCKET_UTIL_H 1 -- --#include --#include --#include --#include --#include --#include --#include --#include "openvswitch/types.h" --#include --#include -- --struct ds; -- --int set_nonblocking(int fd); --void xset_nonblocking(int fd); --void setsockopt_tcp_nodelay(int fd); --int set_dscp(int fd, int family, uint8_t dscp); -- --bool addr_is_ipv6(const char *host_name); --int lookup_ip(const char *host_name, struct in_addr *address); --int lookup_ipv6(const char *host_name, struct in6_addr *address); -- --int lookup_hostname(const char *host_name, struct in_addr *); -- --int get_socket_rcvbuf(int sock); --int check_connection_completion(int fd); --void drain_fd(int fd, size_t n_packets); --ovs_be32 guess_netmask(ovs_be32 ip); -- --void inet_parse_host_port_tokens(char *s, char **hostp, char **portp); --void inet_parse_port_host_tokens(char *s, char **portp, char **hostp); --bool inet_parse_active(const char *target, int default_port, -- struct sockaddr_storage *ssp, -- bool resolve_host, bool *dns_failure); --int inet_open_active(int style, const char *target, int default_port, -- struct sockaddr_storage *ssp, int *fdp, uint8_t dscp); -- --bool inet_parse_passive(const char *target, int default_port, -- struct sockaddr_storage *ssp); --int inet_open_passive(int style, const char *target, int default_port, -- struct sockaddr_storage *ssp, uint8_t dscp, -- bool kernel_print_port); -- --bool inet_parse_address(const char *target, struct sockaddr_storage *); -- --int read_fully(int fd, void *, size_t, size_t *bytes_read); --int write_fully(int fd, const void *, size_t, size_t *bytes_written); -- --int fsync_parent_dir(const char *file_name); --int get_mtime(const char *file_name, struct timespec *mtime); -- --char *describe_fd(int fd); -- --/* Default value of dscp bits for connection between controller and manager. -- * Value of IPTOS_PREC_INTERNETCONTROL = 0xc0 which is defined -- * in is used. */ --#define DSCP_DEFAULT (IPTOS_PREC_INTERNETCONTROL >> 2) -- --/* Functions for working with sockaddr that might contain an IPv4 or -- * IPv6 address. */ --bool sa_is_ip(const struct sockaddr *); --uint16_t sa_get_port(const struct sockaddr *); --struct in6_addr sa_get_address(const struct sockaddr *); --void sa_format_address(const struct sockaddr *, struct ds *); --void sa_format_address_nobracks(const struct sockaddr *, struct ds *); --size_t sa_length(const struct sockaddr *); -- --/* Functions for working with sockaddr_storage that might contain an IPv4 or -- * IPv6 address. */ --bool ss_is_ip(const struct sockaddr_storage *); --uint16_t ss_get_port(const struct sockaddr_storage *); --struct in6_addr ss_get_address(const struct sockaddr_storage *); --void ss_format_address(const struct sockaddr_storage *, struct ds *); --void ss_format_address_nobracks(const struct sockaddr_storage *, struct ds *); --size_t ss_length(const struct sockaddr_storage *); -- --const char *sock_strerror(int error); -- --#ifndef _WIN32 --void xpipe(int fds[2]); --void xpipe_nonblocking(int fds[2]); -- --int drain_rcvbuf(int fd); -- --int make_unix_socket(int style, bool nonblock, -- const char *bind_path, const char *connect_path); --int get_unix_name_len(const struct sockaddr_un *sun, socklen_t sun_len); -- --/* Universal sendmmsg and recvmmsg support on Linux. -- * -- * New enough Linux supports sendmmsg and recvmmsg, but older versions do not. -- * We add the following infrastructure to allow all code on Linux to use -- * sendmmsg and recvmmsg, regardless of platform support: -- * -- * - For platforms that lack these functions entirely, we emulate them. -- * -- * - With newer glibc but an old kernel, sendmmsg() and recvmmsg() fail with -- * ENOSYS. To compensate, even if these functions appear to be available, we -- * wrap them with handlers that use our emulation in this case. -- */ --#ifdef __linux__ --#ifndef HAVE_STRUCT_MMSGHDR_MSG_LEN --struct mmsghdr { -- struct msghdr msg_hdr; -- unsigned int msg_len; --}; --#endif -- --#ifndef HAVE_SENDMMSG --int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int); --int recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *); --#else --#define sendmmsg wrap_sendmmsg --int wrap_sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int); --#define recvmmsg wrap_recvmmsg --int wrap_recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *); --#endif --#endif /* __linux__ */ -- --/* Helpers for calling ioctl() on an AF_INET socket. */ --struct ifreq; --int af_inet_ioctl(unsigned long int command, const void *arg); --int af_inet_ifreq_ioctl(const char *name, struct ifreq *, -- unsigned long int cmd, const char *cmd_name); -- --#define closesocket close --#endif -- --#ifdef _WIN32 --static inline int make_unix_socket(int style, bool nonblock, -- const char *bind_path, -- const char *connect_path) --{ -- return -EINVAL; --} -- --/* Windows defines the 'optval' argument as char * instead of void *. */ --#define setsockopt(sock, level, optname, optval, optlen) \ -- rpl_setsockopt(sock, level, optname, optval, optlen) --static inline int rpl_setsockopt(int sock, int level, int optname, -- const void *optval, socklen_t optlen) --{ -- return (setsockopt)(sock, level, optname, (const char *)optval, optlen); --} -- --#define getsockopt(sock, level, optname, optval, optlen) \ -- rpl_getsockopt(sock, level, optname, optval, optlen) --static inline int rpl_getsockopt(int sock, int level, int optname, -- void *optval, socklen_t *optlen) --{ -- return (getsockopt)(sock, level, optname, (char *)optval, optlen); --} --#endif -- --/* In Windows platform, errno is not set for socket calls. -- * The last error has to be gotten from WSAGetLastError(). */ --static inline int sock_errno(void) --{ --#ifdef _WIN32 -- return WSAGetLastError(); --#else -- return errno; --#endif --} -- --#endif /* socket-util.h */ -Index: openvswitch-2.17.2/lib/sort.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/sort.h -+++ /dev/null -@@ -1,26 +0,0 @@ --/* Copyright (c) 2009 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef SORT_H --#define SORT_H 1 -- --#include -- --void sort(size_t count, -- int (*compare)(size_t a, size_t b, void *aux), -- void (*swap)(size_t a, size_t b, void *aux), -- void *aux); -- --#endif /* sort.h */ -Index: openvswitch-2.17.2/lib/stopwatch.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/stopwatch.h -+++ /dev/null -@@ -1,59 +0,0 @@ --/* Copyright (c) 2017 Red Hat, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef STOPWATCH_H --#define STOPWATCH_H 1 -- --#include -- --enum stopwatch_units { -- SW_MS, -- SW_US, -- SW_NS, --}; -- --struct stopwatch_stats { -- unsigned long long count; /* Total number of samples. */ -- enum stopwatch_units unit; /* Unit of following values. */ -- unsigned long long max; /* Maximum value. */ -- unsigned long long min; /* Minimum value. */ -- double pctl_95; /* 95th percentile. */ -- double ewma_50; /* Exponentially weighted moving average -- (alpha 0.50). */ -- double ewma_1; /* Exponentially weighted moving average -- (alpha 0.01). */ --}; -- --/* Create a new stopwatch. -- * The "units" are not used for any calculations but are printed when -- * statistics are requested. -- */ --void stopwatch_create(const char *name, enum stopwatch_units units); -- --/* Start a stopwatch. */ --void stopwatch_start(const char *name, unsigned long long ts); -- --/* Stop a stopwatch. The elapsed time will be used for updating statistics -- * for this stopwatch. -- */ --void stopwatch_stop(const char *name, unsigned long long ts); -- --/* Retrieve statistics calculated from collected samples */ --bool stopwatch_get_stats(const char *name, struct stopwatch_stats *stats); -- --/* Block until all enqueued samples have been processed. */ --void stopwatch_sync(void); -- --#endif /* stopwatch.h */ -Index: openvswitch-2.17.2/lib/stream-ssl.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/stream-ssl.h -+++ /dev/null -@@ -1,66 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ --#ifndef STREAM_SSL_H --#define STREAM_SSL_H 1 -- --#include -- --bool stream_ssl_is_configured(void); --void stream_ssl_set_private_key_file(const char *file_name); --void stream_ssl_set_certificate_file(const char *file_name); --void stream_ssl_set_ca_cert_file(const char *file_name, bool bootstrap); --void stream_ssl_set_peer_ca_cert_file(const char *file_name); --void stream_ssl_set_key_and_cert(const char *private_key_file, -- const char *certificate_file); --void stream_ssl_set_protocols(const char *arg); --void stream_ssl_set_ciphers(const char *arg); -- --#define SSL_OPTION_ENUMS \ -- OPT_SSL_PROTOCOLS, \ -- OPT_SSL_CIPHERS -- --#define STREAM_SSL_LONG_OPTIONS \ -- {"private-key", required_argument, NULL, 'p'}, \ -- {"certificate", required_argument, NULL, 'c'}, \ -- {"ca-cert", required_argument, NULL, 'C'}, \ -- {"ssl-protocols", required_argument, NULL, OPT_SSL_PROTOCOLS}, \ -- {"ssl-ciphers", required_argument, NULL, OPT_SSL_CIPHERS} -- --#define STREAM_SSL_OPTION_HANDLERS \ -- case 'p': \ -- stream_ssl_set_private_key_file(optarg); \ -- break; \ -- \ -- case 'c': \ -- stream_ssl_set_certificate_file(optarg); \ -- break; \ -- \ -- case 'C': \ -- stream_ssl_set_ca_cert_file(optarg, false); \ -- break; \ -- \ -- case OPT_SSL_PROTOCOLS: \ -- stream_ssl_set_protocols(optarg); \ -- break; \ -- \ -- case OPT_SSL_CIPHERS: \ -- stream_ssl_set_ciphers(optarg); \ -- break; -- --#define STREAM_SSL_CASES \ -- case 'p': case 'c': case 'C': case OPT_SSL_PROTOCOLS: case OPT_SSL_CIPHERS: -- --#endif /* stream-ssl.h */ -Index: openvswitch-2.17.2/lib/svec.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/svec.h -+++ /dev/null -@@ -1,80 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2011 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef SVEC_H --#define SVEC_H 1 -- --#include --#include -- --#ifdef __cplusplus --extern "C" { --#endif -- --struct svec { -- char **names; -- size_t n; -- size_t allocated; --}; -- --#define SVEC_EMPTY_INITIALIZER { NULL, 0, 0 } -- --void svec_init(struct svec *); --void svec_clone(struct svec *, const struct svec *); --void svec_destroy(struct svec *); --void svec_clear(struct svec *); --bool svec_is_empty(const struct svec *); --void svec_add(struct svec *, const char *); --void svec_add_nocopy(struct svec *, char *); --void svec_del(struct svec *, const char *); --void svec_append(struct svec *, const struct svec *); --void svec_terminate(struct svec *); --void svec_sort(struct svec *); --void svec_sort_unique(struct svec *); --void svec_unique(struct svec *); --void svec_compact(struct svec *); --void svec_shuffle(struct svec *); --void svec_diff(const struct svec *a, const struct svec *b, -- struct svec *a_only, struct svec *both, struct svec *b_only); --bool svec_contains(const struct svec *, const char *); --bool svec_contains_unsorted(const struct svec *, const char *); --size_t svec_find(const struct svec *, const char *); --bool svec_is_sorted(const struct svec *); --bool svec_is_unique(const struct svec *); --const char *svec_get_duplicate(const struct svec *); --void svec_swap(struct svec *a, struct svec *b); --void svec_print(const struct svec *svec, const char *title); --void svec_parse_words(struct svec *svec, const char *words); --bool svec_equal(const struct svec *, const struct svec *); --char *svec_join(const struct svec *, -- const char *delimiter, const char *terminator); --const char *svec_back(const struct svec *); --void svec_pop_back(struct svec *); -- --/* Iterates over the names in SVEC, assigning each name in turn to NAME and its -- * index to INDEX. */ --#define SVEC_FOR_EACH(INDEX, NAME, SVEC) \ -- for ((INDEX) = 0; \ -- ((INDEX) < (SVEC)->n \ -- ? (NAME) = (SVEC)->names[INDEX], 1 \ -- : 0); \ -- (INDEX)++) -- --#ifdef __cplusplus --} --#endif -- --#endif /* svec.h */ -Index: openvswitch-2.17.2/lib/table.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/table.h -+++ /dev/null -@@ -1,139 +0,0 @@ --/* -- * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef TABLE_H --#define TABLE_H 1 -- --#include --#include --#include "openvswitch/compiler.h" --#include "openvswitch/json.h" -- --struct ds; --struct table_style; -- --/* Manipulating tables and their rows and columns. */ -- --struct table { -- struct cell *cells; -- struct column *columns; -- size_t n_columns, allocated_columns; -- size_t n_rows, allocated_rows; -- size_t current_column; -- char *caption; -- bool timestamp; --}; -- --void table_init(struct table *); --void table_destroy(struct table *); --void table_set_caption(struct table *, char *caption); --void table_set_timestamp(struct table *, bool timestamp); -- --void table_add_column(struct table *, const char *heading, ...) -- OVS_PRINTF_FORMAT(2, 3); --void table_add_row(struct table *); -- --/* Table cells. */ -- --struct cell { -- /* Literal text. */ -- char *text; -- -- /* JSON. */ -- struct json *json; -- const struct ovsdb_type *type; --}; -- --struct cell *table_add_cell(struct table *); -- --/* Table formatting. */ -- --enum table_format { -- TF_TABLE, /* 2-d table. */ -- TF_LIST, /* One cell per line, one row per paragraph. */ -- TF_HTML, /* HTML table. */ -- TF_CSV, /* Comma-separated lines. */ -- TF_JSON /* JSON. */ --}; -- --enum cell_format { -- CF_STRING, /* String format. */ -- CF_BARE, /* String format without most punctuation. */ -- CF_JSON /* JSON. */ --}; -- --struct table_style { -- enum table_format format; /* TF_*. */ -- enum cell_format cell_format; /* CF_*. */ -- bool headings; /* Include headings? */ -- int json_flags; /* CF_JSON: Flags for json_to_string(). */ -- int max_column_width; /* CF_STRING: Limit for column width. */ --}; -- --#define TABLE_STYLE_DEFAULT { TF_LIST, CF_STRING, true, JSSF_SORT, 0 } --static const struct table_style table_style_default = TABLE_STYLE_DEFAULT; -- --#define TABLE_OPTION_ENUMS \ -- OPT_NO_HEADINGS, \ -- OPT_PRETTY, \ -- OPT_BARE, \ -- OPT_MAX_COLUMN_WIDTH -- --#define TABLE_LONG_OPTIONS \ -- {"format", required_argument, NULL, 'f'}, \ -- {"data", required_argument, NULL, 'd'}, \ -- {"no-headings", no_argument, NULL, OPT_NO_HEADINGS}, \ -- {"pretty", no_argument, NULL, OPT_PRETTY}, \ -- {"bare", no_argument, NULL, OPT_BARE}, \ -- {"max-column-width", required_argument, NULL, OPT_MAX_COLUMN_WIDTH} -- --#define TABLE_OPTION_HANDLERS(STYLE) \ -- case 'f': \ -- table_parse_format(STYLE, optarg); \ -- break; \ -- \ -- case 'd': \ -- table_parse_cell_format(STYLE, optarg); \ -- break; \ -- \ -- case OPT_NO_HEADINGS: \ -- (STYLE)->headings = false; \ -- break; \ -- \ -- case OPT_PRETTY: \ -- (STYLE)->json_flags |= JSSF_PRETTY; \ -- break; \ -- \ -- case OPT_BARE: \ -- (STYLE)->format = TF_LIST; \ -- (STYLE)->cell_format = CF_BARE; \ -- (STYLE)->headings = false; \ -- break; \ -- \ -- case OPT_MAX_COLUMN_WIDTH: \ -- (STYLE)->max_column_width = atoi(optarg); \ -- break; -- --void table_parse_format(struct table_style *, const char *format); --void table_parse_cell_format(struct table_style *, const char *format); -- --void table_print(const struct table *, const struct table_style *); --void table_format(const struct table *, const struct table_style *, -- struct ds *); --void table_format_reset(void); --void table_usage(void); -- --#endif /* table.h */ -Index: openvswitch-2.17.2/lib/unixctl.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/unixctl.h -+++ /dev/null -@@ -1,55 +0,0 @@ --/* -- * Copyright (c) 2008, 2009, 2011 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef UNIXCTL_H --#define UNIXCTL_H 1 -- --#ifdef __cplusplus --extern "C" { --#endif -- --/* Server for Unix domain socket control connection. */ --struct unixctl_server; --int unixctl_server_create(const char *path, struct unixctl_server **); --void unixctl_server_run(struct unixctl_server *); --void unixctl_server_wait(struct unixctl_server *); --void unixctl_server_destroy(struct unixctl_server *); -- --const char *unixctl_server_get_path(const struct unixctl_server *); -- --/* Client for Unix domain socket control connection. */ --struct jsonrpc; --int unixctl_client_create(const char *path, struct jsonrpc **client); --int unixctl_client_transact(struct jsonrpc *client, -- const char *command, -- int argc, char *argv[], -- char **result, char **error); -- --/* Command registration. */ --struct unixctl_conn; --typedef void unixctl_cb_func(struct unixctl_conn *, -- int argc, const char *argv[], void *aux); --void unixctl_command_register(const char *name, const char *usage, -- int min_args, int max_args, -- unixctl_cb_func *cb, void *aux); --void unixctl_command_reply_error(struct unixctl_conn *, const char *error); --void unixctl_command_reply(struct unixctl_conn *, const char *body); -- --#ifdef __cplusplus --} --#endif -- --#endif /* unixctl.h */ -Index: openvswitch-2.17.2/lib/uuid.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/uuid.h -+++ /dev/null -@@ -1,92 +0,0 @@ --/* Copyright (c) 2008, 2009, 2010, 2016, 2017 Nicira, Inc. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at: -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef UUID_H --#define UUID_H 1 -- --#include "openvswitch/uuid.h" -- --#ifdef __cplusplus --extern "C" { --#endif -- --/* An initializer or expression for an all-zero UUID. */ --#define UUID_ZERO ((struct uuid) { .parts = { 0, 0, 0, 0 } }) -- --/* Formats a UUID as a string, in the conventional format. -- * -- * Example: -- * struct uuid uuid = ...; -- * printf("This UUID is "UUID_FMT"\n", UUID_ARGS(&uuid)); -- * -- */ --#define UUID_LEN 36 --#define UUID_FMT "%08x-%04x-%04x-%04x-%04x%08x" --#define UUID_ARGS(UUID) \ -- ((unsigned int) ((UUID)->parts[0])), \ -- ((unsigned int) ((UUID)->parts[1] >> 16)), \ -- ((unsigned int) ((UUID)->parts[1] & 0xffff)), \ -- ((unsigned int) ((UUID)->parts[2] >> 16)), \ -- ((unsigned int) ((UUID)->parts[2] & 0xffff)), \ -- ((unsigned int) ((UUID)->parts[3])) -- --/* Returns a hash value for 'uuid'. This hash value is the same regardless of -- * whether we are running on a 32-bit or 64-bit or big-endian or little-endian -- * architecture. */ --static inline size_t --uuid_hash(const struct uuid *uuid) --{ -- return uuid->parts[0]; --} -- --/* Returns true if 'a == b', false otherwise. */ --static inline bool --uuid_equals(const struct uuid *a, const struct uuid *b) --{ -- return (a->parts[0] == b->parts[0] -- && a->parts[1] == b->parts[1] -- && a->parts[2] == b->parts[2] -- && a->parts[3] == b->parts[3]); --} -- --/* Returns the first 'n' hex digits of 'uuid', for 0 < 'n' <= 8. -- * -- * This is useful for displaying a few leading digits of the uuid, e.g. to -- * display 4 digits: -- * printf("%04x", uuid_prefix(uuid, 4)); -- */ --static inline unsigned int --uuid_prefix(const struct uuid *uuid, int digits) --{ -- return (uuid->parts[0] >> (32 - 4 * digits)); --} -- --void uuid_init(void); --void uuid_generate(struct uuid *); --struct uuid uuid_random(void); --void uuid_zero(struct uuid *); --bool uuid_is_zero(const struct uuid *); --int uuid_compare_3way(const struct uuid *, const struct uuid *); --bool uuid_from_string(struct uuid *, const char *); --bool uuid_from_string_prefix(struct uuid *, const char *); --int uuid_is_partial_string(const char *); --int uuid_is_partial_match(const struct uuid *, const char *match); --void uuid_set_bits_v4(struct uuid *); -- --#ifdef __cplusplus --} --#endif -- --#endif /* uuid.h */ diff --git a/a77ad9693c8b49055389559187fe74eddb619746.patch b/a77ad9693c8b49055389559187fe74eddb619746.patch deleted file mode 100644 index 8c948fe..0000000 --- a/a77ad9693c8b49055389559187fe74eddb619746.patch +++ /dev/null @@ -1,355 +0,0 @@ -From a77ad9693c8b49055389559187fe74eddb619746 Mon Sep 17 00:00:00 2001 -From: David Marchand -Date: Wed, 29 Jun 2022 09:32:24 +0200 -Subject: [PATCH] dpif-netdev: Refactor AVX512 runtime checks. - -As described in the bugzilla below, cpu_has_isa code may be compiled -with some AVX512 instructions in it, because cpu.c is built as part of -the libopenvswitchavx512. -This is a problem when this function (supposed to probe for AVX512 -instructions availability) is invoked from generic OVS code, on older -CPUs that don't support them. - -For the same reason, dpcls_subtable_avx512_gather_probe, -dp_netdev_input_outer_avx512_probe, mfex_avx512_probe and -mfex_avx512_vbmi_probe are potential runtime bombs and can't either be -built as part of libopenvswitchavx512. - -Move cpu.c to be part of the "normal" libopenvswitch. -And move other helpers in generic OVS code. - -Note: -- dpcls_subtable_avx512_gather_probe is split in two, because it also - needs to do its own magic, -- while moving those helpers, prefer direct calls to cpu_has_isa and - avoid cast to intermediate integer variables when a simple boolean - is enough, - -Fixes: 352b6c7116cd ("dpif-lookup: add avx512 gather implementation.") -Fixes: abb807e27dd4 ("dpif-netdev: Add command to switch dpif implementation.") -Fixes: 250ceddcc2d0 ("dpif-netdev/mfex: Add AVX512 based optimized miniflow extract") -Fixes: b366fa2f4947 ("dpif-netdev: Call cpuid for x86 isa availability.") -Reported-at: https://bugzilla.redhat.com/2100393 -Reported-by: Ales Musil -Co-authored-by: Ales Musil -Signed-off-by: Ales Musil -Signed-off-by: David Marchand -Acked-by: Sunil Pai G -Acked-by: Ales Musil -Signed-off-by: Ilya Maximets ---- - lib/automake.mk | 4 +-- - lib/dpif-netdev-avx512.c | 14 --------- - lib/dpif-netdev-extract-avx512.c | 43 -------------------------- - lib/dpif-netdev-lookup-avx512-gather.c | 12 ++----- - lib/dpif-netdev-lookup.c | 15 +++++++++ - lib/dpif-netdev-lookup.h | 3 +- - lib/dpif-netdev-private-dpif.c | 14 +++++++++ - lib/dpif-netdev-private-dpif.h | 5 +-- - lib/dpif-netdev-private-extract.c | 38 +++++++++++++++++++++++ - lib/dpif-netdev-private-extract.h | 4 +-- - 10 files changed, 75 insertions(+), 77 deletions(-) - -Index: openvswitch-2.17.2/lib/automake.mk -=================================================================== ---- openvswitch-2.17.2.orig/lib/automake.mk -+++ openvswitch-2.17.2/lib/automake.mk -@@ -38,8 +38,6 @@ lib_libopenvswitchavx512_la_CFLAGS = \ - -fPIC \ - $(AM_CFLAGS) - lib_libopenvswitchavx512_la_SOURCES = \ -- lib/cpu.c \ -- lib/cpu.h \ - lib/dpif-netdev-lookup-avx512-gather.c \ - lib/dpif-netdev-extract-avx512.c \ - lib/dpif-netdev-avx512.c -@@ -89,6 +87,8 @@ lib_libopenvswitch_la_SOURCES = \ - lib/conntrack.h \ - lib/coverage.c \ - lib/coverage.h \ -+ lib/cpu.c \ -+ lib/cpu.h \ - lib/crc32c.c \ - lib/crc32c.h \ - lib/csum.c \ -Index: openvswitch-2.17.2/lib/dpif-netdev-avx512.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-avx512.c -+++ openvswitch-2.17.2/lib/dpif-netdev-avx512.c -@@ -20,7 +20,6 @@ - - #include - --#include "cpu.h" - #include "dpif-netdev.h" - #include "dpif-netdev-perf.h" - #include "dpif-netdev-private.h" -@@ -60,19 +59,6 @@ struct dpif_userdata { - }; - - int32_t --dp_netdev_input_outer_avx512_probe(void) --{ -- bool avx512f_available = cpu_has_isa(OVS_CPU_ISA_X86_AVX512F); -- bool bmi2_available = cpu_has_isa(OVS_CPU_ISA_X86_BMI2); -- -- if (!avx512f_available || !bmi2_available) { -- return -ENOTSUP; -- } -- -- return 0; --} -- --int32_t - dp_netdev_input_outer_avx512(struct dp_netdev_pmd_thread *pmd, - struct dp_packet_batch *packets, - odp_port_t in_port) -Index: openvswitch-2.17.2/lib/dpif-netdev-extract-avx512.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-extract-avx512.c -+++ openvswitch-2.17.2/lib/dpif-netdev-extract-avx512.c -@@ -42,7 +42,6 @@ - #include - #include - --#include "cpu.h" - #include "internal/flow.h" - - #include "dpif-netdev-private-dpcls.h" -@@ -659,47 +658,5 @@ DECLARE_MFEX_FUNC(ip_udp, PROFILE_ETH_IP - DECLARE_MFEX_FUNC(ip_tcp, PROFILE_ETH_IPV4_TCP) - DECLARE_MFEX_FUNC(dot1q_ip_udp, PROFILE_ETH_VLAN_IPV4_UDP) - DECLARE_MFEX_FUNC(dot1q_ip_tcp, PROFILE_ETH_VLAN_IPV4_TCP) -- -- --static int32_t --avx512_isa_probe(uint32_t needs_vbmi) --{ -- static enum ovs_cpu_isa isa_required[] = { -- OVS_CPU_ISA_X86_AVX512F, -- OVS_CPU_ISA_X86_AVX512BW, -- OVS_CPU_ISA_X86_BMI2, -- }; -- -- int32_t ret = 0; -- for (uint32_t i = 0; i < ARRAY_SIZE(isa_required); i++) { -- if (!cpu_has_isa(isa_required[i])) { -- ret = -ENOTSUP; -- } -- } -- -- if (needs_vbmi) { -- if (!cpu_has_isa(OVS_CPU_ISA_X86_AVX512VBMI)) { -- ret = -ENOTSUP; -- } -- } -- -- return ret; --} -- --/* Probe functions to check ISA requirements. */ --int32_t --mfex_avx512_probe(void) --{ -- const uint32_t needs_vbmi = 0; -- return avx512_isa_probe(needs_vbmi); --} -- --int32_t --mfex_avx512_vbmi_probe(void) --{ -- const uint32_t needs_vbmi = 1; -- return avx512_isa_probe(needs_vbmi); --} -- - #endif /* __CHECKER__ */ - #endif /* __x86_64__ */ -Index: openvswitch-2.17.2/lib/dpif-netdev-lookup-avx512-gather.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup-avx512-gather.c -+++ openvswitch-2.17.2/lib/dpif-netdev-lookup-avx512-gather.c -@@ -396,18 +396,11 @@ dpcls_avx512_gather_mf_any(struct dpcls_ - } - - dpcls_subtable_lookup_func --dpcls_subtable_avx512_gather_probe(uint32_t u0_bits, uint32_t u1_bits) -+dpcls_subtable_avx512_gather_probe__(uint32_t u0_bits, uint32_t u1_bits, -+ bool use_vpop) - { - dpcls_subtable_lookup_func f = NULL; - -- int avx512f_available = cpu_has_isa(OVS_CPU_ISA_X86_AVX512F); -- int bmi2_available = cpu_has_isa(OVS_CPU_ISA_X86_BMI2); -- if (!avx512f_available || !bmi2_available) { -- return NULL; -- } -- -- int use_vpop = cpu_has_isa(OVS_CPU_ISA_X86_VPOPCNTDQ); -- - CHECK_LOOKUP_FUNCTION(9, 4, use_vpop); - CHECK_LOOKUP_FUNCTION(9, 1, use_vpop); - CHECK_LOOKUP_FUNCTION(5, 3, use_vpop); -Index: openvswitch-2.17.2/lib/dpif-netdev-lookup.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup.c -+++ openvswitch-2.17.2/lib/dpif-netdev-lookup.c -@@ -18,10 +18,25 @@ - #include - #include "dpif-netdev-lookup.h" - -+#include "cpu.h" - #include "openvswitch/vlog.h" - - VLOG_DEFINE_THIS_MODULE(dpif_netdev_lookup); - -+#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__) -+static dpcls_subtable_lookup_func -+dpcls_subtable_avx512_gather_probe(uint32_t u0_bits, uint32_t u1_bits) -+{ -+ if (!cpu_has_isa(OVS_CPU_ISA_X86_AVX512F) -+ || !cpu_has_isa(OVS_CPU_ISA_X86_BMI2)) { -+ return NULL; -+ } -+ -+ return dpcls_subtable_avx512_gather_probe__(u0_bits, u1_bits, -+ cpu_has_isa(OVS_CPU_ISA_X86_VPOPCNTDQ)); -+} -+#endif -+ - /* Actual list of implementations goes here */ - static struct dpcls_subtable_lookup_info_t subtable_lookups[] = { - /* The autovalidator implementation will not be used by default, it must -Index: openvswitch-2.17.2/lib/dpif-netdev-lookup.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup.h -+++ openvswitch-2.17.2/lib/dpif-netdev-lookup.h -@@ -44,7 +44,8 @@ dpcls_subtable_generic_probe(uint32_t u0 - - /* Probe function for AVX-512 gather implementation */ - dpcls_subtable_lookup_func --dpcls_subtable_avx512_gather_probe(uint32_t u0_bit_cnt, uint32_t u1_bit_cnt); -+dpcls_subtable_avx512_gather_probe__(uint32_t u0_bit_cnt, uint32_t u1_bit_cnt, -+ bool use_vpop); - - - /* Subtable registration and iteration helpers */ -Index: openvswitch-2.17.2/lib/dpif-netdev-private-dpif.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-dpif.c -+++ openvswitch-2.17.2/lib/dpif-netdev-private-dpif.c -@@ -22,6 +22,7 @@ - #include - #include - -+#include "cpu.h" - #include "openvswitch/dynamic-string.h" - #include "openvswitch/vlog.h" - #include "internal/util.h" -@@ -33,6 +34,19 @@ enum dpif_netdev_impl_info_idx { - DPIF_NETDEV_IMPL_AVX512 - }; - -+#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__) -+static int32_t -+dp_netdev_input_outer_avx512_probe(void) -+{ -+ if (!cpu_has_isa(OVS_CPU_ISA_X86_AVX512F) -+ || !cpu_has_isa(OVS_CPU_ISA_X86_BMI2)) { -+ return -ENOTSUP; -+ } -+ -+ return 0; -+} -+#endif -+ - /* Actual list of implementations goes here. */ - static struct dpif_netdev_impl_info_t dpif_impls[] = { - /* The default scalar C code implementation. */ -Index: openvswitch-2.17.2/lib/dpif-netdev-private-dpif.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-dpif.h -+++ openvswitch-2.17.2/lib/dpif-netdev-private-dpif.h -@@ -67,10 +67,7 @@ dp_netdev_input(struct dp_netdev_pmd_thr - struct dp_packet_batch *packets, - odp_port_t in_port); - --/* AVX512 enabled DPIF implementation and probe functions. */ --int32_t --dp_netdev_input_outer_avx512_probe(void); -- -+/* AVX512 enabled DPIF implementation function. */ - int32_t - dp_netdev_input_outer_avx512(struct dp_netdev_pmd_thread *pmd, - struct dp_packet_batch *packets, -Index: openvswitch-2.17.2/lib/dpif-netdev-private-extract.c -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-extract.c -+++ openvswitch-2.17.2/lib/dpif-netdev-private-extract.c -@@ -19,6 +19,7 @@ - #include - #include - -+#include "cpu.h" - #include "internal/dp-packet.h" - #include "dpif-netdev-private-dpcls.h" - #include "dpif-netdev-private-extract.h" -@@ -33,6 +34,43 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev_extr - /* Variable to hold the default MFEX implementation. */ - static ATOMIC(miniflow_extract_func) default_mfex_func; - -+#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__) -+static int32_t -+avx512_isa_probe(bool needs_vbmi) -+{ -+ static enum ovs_cpu_isa isa_required[] = { -+ OVS_CPU_ISA_X86_AVX512F, -+ OVS_CPU_ISA_X86_AVX512BW, -+ OVS_CPU_ISA_X86_BMI2, -+ }; -+ -+ for (uint32_t i = 0; i < ARRAY_SIZE(isa_required); i++) { -+ if (!cpu_has_isa(isa_required[i])) { -+ return -ENOTSUP; -+ } -+ } -+ -+ if (needs_vbmi && !cpu_has_isa(OVS_CPU_ISA_X86_AVX512VBMI)) { -+ return -ENOTSUP; -+ } -+ -+ return 0; -+} -+ -+/* Probe functions to check ISA requirements. */ -+static int32_t -+mfex_avx512_probe(void) -+{ -+ return avx512_isa_probe(false); -+} -+ -+static int32_t -+mfex_avx512_vbmi_probe(void) -+{ -+ return avx512_isa_probe(true); -+} -+#endif -+ - /* Implementations of available extract options and - * the implementations are always in order of preference. - */ -Index: openvswitch-2.17.2/lib/dpif-netdev-private-extract.h -=================================================================== ---- openvswitch-2.17.2.orig/lib/dpif-netdev-private-extract.h -+++ openvswitch-2.17.2/lib/dpif-netdev-private-extract.h -@@ -176,10 +176,8 @@ mfex_study_traffic(struct dp_packet_batc - int - mfex_set_study_pkt_cnt(uint32_t pkt_cmp_count, const char *name); - --/* AVX512 MFEX Probe and Implementations functions. */ -+/* AVX512 MFEX Implementation functions. */ - #ifdef __x86_64__ --int32_t mfex_avx512_probe(void); --int32_t mfex_avx512_vbmi_probe(void); - - #define DECLARE_AVX512_MFEX_PROTOTYPE(name) \ - uint32_t \ diff --git a/install-ovsdb-tools.patch b/install-ovsdb-tools.patch index 925a57b..e8556e7 100644 --- a/install-ovsdb-tools.patch +++ b/install-ovsdb-tools.patch @@ -1,7 +1,8 @@ -diff -Nur openvswitch-2.17.0/ovsdb/automake.mk new/ovsdb/automake.mk ---- openvswitch-2.17.0/ovsdb/automake.mk 2022-02-17 23:15:55.240680736 +0100 -+++ new/ovsdb/automake.mk 2022-02-27 20:21:59.358719903 +0100 -@@ -88,8 +88,9 @@ +diff --git a/ovsdb/automake.mk b/ovsdb/automake.mk +index eba713bb6..f1c40d019 100644 +--- a/ovsdb/automake.mk ++++ b/ovsdb/automake.mk +@@ -88,8 +88,9 @@ CLEANFILES += ovsdb/ovsdb-server.1 MAN_ROOTS += ovsdb/ovsdb-server.1.in # ovsdb-idlc @@ -12,7 +13,7 @@ diff -Nur openvswitch-2.17.0/ovsdb/automake.mk new/ovsdb/automake.mk MAN_ROOTS += ovsdb/ovsdb-idlc.1 CLEANFILES += ovsdb/ovsdb-idlc SUFFIXES += .ovsidl .ovsschema -@@ -112,14 +113,18 @@ +@@ -112,14 +113,18 @@ CLEANFILES += $(OVSIDL_BUILT) # at least for now. $(OVSIDL_BUILT): ovsdb/ovsdb-idlc.in python/ovs/dirs.py diff --git a/openvswitch-2.17.2-Fix-tests-with-GNU-grep-3.8.patch b/openvswitch-2.17.2-Fix-tests-with-GNU-grep-3.8.patch deleted file mode 100644 index 027e14a..0000000 --- a/openvswitch-2.17.2-Fix-tests-with-GNU-grep-3.8.patch +++ /dev/null @@ -1,468 +0,0 @@ -From 28fec7e88f0faf877a1da4fcfb4b629211fff84c Mon Sep 17 00:00:00 2001 -From: Andreas Stieger -Date: Mon, 12 Sep 2022 21:38:46 +0200 -Subject: [PATCH] Fix tests with GNU grep 3.8 - -GNU grep 3.8 started to emit warnings when invoking egrep/fgrep. In some -cases this breaks tests that check stderr. Replace the commands with -their grep -E and grep -F counterparts throughout. - -Signed-off-by: Andreas Stieger -Reported-at: https://bugzilla.opensuse.org/show_bug.cgi?id=1203239 - -https://github.com/openvswitch/ovs/pull/395 -https://bugzilla.opensuse.org/show_bug.cgi?id=1203239 ---- - tests/ofproto-dpif.at | 12 +-- - tests/ovs-macros.at | 2 +- - tests/ovs-ofctl.at | 6 +- - tests/system-dpdk-macros.at | 2 +- - tests/system-dpdk.at | 48 ++++----- - tests/system-offloads-traffic.at | 4 +- - tests/system-traffic.at | 162 +++++++++++++++---------------- - tests/tunnel-push-pop.at | 6 +- - 8 files changed, 121 insertions(+), 121 deletions(-) - -Index: openvswitch-2.17.2/tests/ofproto-dpif.at -=================================================================== ---- openvswitch-2.17.2.orig/tests/ofproto-dpif.at -+++ openvswitch-2.17.2/tests/ofproto-dpif.at -@@ -126,7 +126,7 @@ dnl bring the primary back and verify th - dnl primary. - ovs-appctl netdev-dummy/set-admin-state p1 down - ovs-appctl time/warp 100 --OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | fgrep 'member p1: disabled'`"]) -+OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | grep -F 'member p1: disabled'`"]) - ovs-appctl netdev-dummy/set-admin-state p1 up - ovs-appctl time/warp 100 - OVS_WAIT_UNTIL_EQUAL([ovs-appctl bond/show | STRIP_RECIRC_ID | STRIP_ACTIVE_MEMBER_MAC], [dnl -@@ -157,7 +157,7 @@ dnl Now delete the primary and verify th - dnl primary is no longer an member - ovs-vsctl --id=@p1 get Interface p1 -- remove Port bond0 interfaces @p1 - ovs-appctl time/warp 100 --OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | fgrep 'active-backup primary: p1 (no such member)'`"]) -+OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | grep -F 'active-backup primary: p1 (no such member)'`"]) - - dnl Now re-add the primary and verify that the output shows that the - dnl primary is available again. -@@ -336,9 +336,9 @@ ovs-appctl time/warp 100 - AT_CHECK([ovs-appctl dpif/dump-flows br1 > br1_flows.txt]) - # Make sure there is resonable distribution to all three ports. - # We don't want to make this check precise, in case hash function changes. --AT_CHECK([test `egrep 'in_port\(4\)' br1_flows.txt |wc -l` -gt 3]) --AT_CHECK([test `egrep 'in_port\(5\)' br1_flows.txt |wc -l` -gt 3]) --AT_CHECK([test `egrep 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3]) -+AT_CHECK([test `grep -E 'in_port\(4\)' br1_flows.txt |wc -l` -gt 3]) -+AT_CHECK([test `grep -E 'in_port\(5\)' br1_flows.txt |wc -l` -gt 3]) -+AT_CHECK([test `grep -E 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3]) - OVS_VSWITCHD_STOP - AT_CLEANUP - -@@ -5464,7 +5464,7 @@ ovs-vsctl \ - - flow="in_port=1" - AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout]) --AT_CHECK([tail -1 stdout | egrep "trunc\(200\),2,trunc\(300\),3,100|trunc\(300\),3,trunc\(200\),2,100"], [0], [stdout]) -+AT_CHECK([tail -1 stdout | grep -E "trunc\(200\),2,trunc\(300\),3,100|trunc\(300\),3,trunc\(200\),2,100"], [0], [stdout]) - - OVS_VSWITCHD_STOP - AT_CLEANUP -Index: openvswitch-2.17.2/tests/ovs-macros.at -=================================================================== ---- openvswitch-2.17.2.orig/tests/ovs-macros.at -+++ openvswitch-2.17.2/tests/ovs-macros.at -@@ -134,7 +134,7 @@ parent_pid () { - # e.g. Alpine Linux) is noncompliant, so we use a Linux-specific approach - # when it's available. We check the format of the status file to avoid - # the NetBSD file with the same name but different contents. -- if egrep '^PPid:[[:space:]]*[0-9]*$' /proc/$1/status > /dev/null 2>&1; then -+ if grep -E '^PPid:[[:space:]]*[0-9]*$' /proc/$1/status > /dev/null 2>&1; then - sed -n 's/^PPid: \([0-9]*\)/\1/p' /proc/$1/status - else - ps -o ppid= -p $1 -Index: openvswitch-2.17.2/tests/ovs-ofctl.at -=================================================================== ---- openvswitch-2.17.2.orig/tests/ovs-ofctl.at -+++ openvswitch-2.17.2/tests/ovs-ofctl.at -@@ -3243,9 +3243,9 @@ AT_CHECK([ovs-testcontroller -vsyslog:of - OVS_WAIT_UNTIL([test -e testcontroller]) - - dnl check for some of the initial handshake messages --OVS_WAIT_UNTIL([egrep "OFPT_FEATURES_REQUEST" snoopbr0.txt >/dev/null 2>&1]) --OVS_WAIT_UNTIL([egrep "OFPT_FEATURES_REPLY" snoopbr0.txt >/dev/null 2>&1]) --OVS_WAIT_UNTIL([egrep "OFPT_SET_CONFIG" snoopbr0.txt >/dev/null 2>&1]) -+OVS_WAIT_UNTIL([grep -E "OFPT_FEATURES_REQUEST" snoopbr0.txt >/dev/null 2>&1]) -+OVS_WAIT_UNTIL([grep -E "OFPT_FEATURES_REPLY" snoopbr0.txt >/dev/null 2>&1]) -+OVS_WAIT_UNTIL([grep -E "OFPT_SET_CONFIG" snoopbr0.txt >/dev/null 2>&1]) - - dnl need to suppress the 'connection failed' WARN message in ovs-vswitchd - dnl because we need ovs-vswitchd to have the controller config before starting -Index: openvswitch-2.17.2/tests/system-dpdk-macros.at -=================================================================== ---- openvswitch-2.17.2.orig/tests/system-dpdk-macros.at -+++ openvswitch-2.17.2/tests/system-dpdk-macros.at -@@ -6,7 +6,7 @@ - m4_define([OVS_DPDK_PRE_CHECK], - [dnl Check Hugepages - AT_CHECK([cat /proc/meminfo], [], [stdout]) -- AT_SKIP_IF([egrep 'HugePages_Free: *0' stdout], [], [stdout]) -+ AT_SKIP_IF([grep -E 'HugePages_Free: *0' stdout], [], [stdout]) - AT_CHECK([mount], [], [stdout]) - AT_CHECK([grep 'hugetlbfs' stdout], [], [stdout], []) - -Index: openvswitch-2.17.2/tests/system-offloads-traffic.at -=================================================================== ---- openvswitch-2.17.2.orig/tests/system-offloads-traffic.at -+++ openvswitch-2.17.2/tests/system-offloads-traffic.at -@@ -90,7 +90,7 @@ AT_CHECK([tc -o -s -d filter show dev ov - rate 100Kbit burst 1280b - ]) - AT_CHECK([tc -s -d filter show dev ovs-p0 ingress | -- egrep "basic|matchall" > /dev/null], [0]) -+ grep -E "basic|matchall" > /dev/null], [0]) - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP - -@@ -139,7 +139,7 @@ AT_CHECK([tc -o -s -d filter show dev ov - pkts_rate 100000 pkts_burst 10000 - ]) - AT_CHECK([tc -s -d filter show dev ovs-p0 ingress | -- egrep "basic|matchall" > /dev/null], [0]) -+ grep -E "basic|matchall" > /dev/null], [0]) - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP - -Index: openvswitch-2.17.2/tests/system-traffic.at -=================================================================== ---- openvswitch-2.17.2.orig/tests/system-traffic.at -+++ openvswitch-2.17.2/tests/system-traffic.at -@@ -819,11 +819,11 @@ dnl ADD_NATIVE_TUNNEL([gretap], [ns_gre0 - dnl Now, check the overlay by sending out raw arp and icmp packets. - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff00000003080045000042ec2c4000402ff3bcac1f0101ac1f016400006558fffffffffffff2ff0000000408060001080006040001f2ff000000040a0101010000000000000a010164 actions=NORMAL" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "IP 172.31.1.100 > 172.31.1.1: GREv0, length 46: ARP, Reply 10.1.1.100 is-at f2:ff:00:00:00:01.* length 28" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "IP 172.31.1.100 > 172.31.1.1: GREv0, length 46: ARP, Reply 10.1.1.100 is-at f2:ff:00:00:00:01.* length 28" 2>&1 1>/dev/null]) - - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000308004500007aec8e4000402ff322ac1f0101ac1f016400006558f2ff00000001f2ff00000004080045000054548f40004001cfb30a0101010a0101640800e6e829270003e1a3435b00000000ff1a050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 actions=NORMAL" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "IP 172.31.1.100 > 172.31.1.1: GREv0, length 102: IP 10.1.1.100 > 10.1.1.1: ICMP echo reply,.* length 64$" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "IP 172.31.1.100 > 172.31.1.1: GREv0, length 102: IP 10.1.1.100 > 10.1.1.1: ICMP echo reply,.* length 64$" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -864,15 +864,15 @@ dnl Okay, now send out an arp request fr - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000308004500004e151d4000402fcac0ac1f0101ac1f0164100088be000000061000000100000007fffffffffffff2ff0000000408060001080006040001f2ff000000040a0101010000000000000a010164 actions=normal" - - dnl 0002 is arp reply, followed by mac address of 10.1.1.100. --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0030: 0806 0001 0800 0604 0002 f2ff 0000 0001" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0040: 0a01 0164 f2ff 0000 0004 0a01 0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0030: 0806 0001 0800 0604 0002 f2ff 0000 0001" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0040: 0a01 0164 f2ff 0000 0004 0a01 0101" 2>&1 1>/dev/null]) - - dnl Okay, now check the overlay with raw icmp packets. --AT_FAIL_IF([cat p0.pcap | egrep "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 122" 2>&1 1>/dev/null]) -+AT_FAIL_IF([cat p0.pcap | grep -E "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 122" 2>&1 1>/dev/null]) - - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000308004500008e70cb4000402f6ed2ac1f0101ac1f0164100088be000000051000000100000007f2ff00000001f2ff0000000408004500005c4a3340004001da070a0101010a010164080084f238fb0001f36a6b5b0000000021870e0000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f actions=normal" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 122" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 122" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -916,17 +916,17 @@ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i - dnl Okay, send raw arp request and icmp echo request. - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff00000003080045000052373d4000402fa89cac1f0101ac1f0164100088be00000006200000016f54b41700008078fffffffffffff2ff0000000408060001080006040001f2ff000000040a0101010000000000000a010164 actions=normal" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0030: 0000 0001 0806 0001 0800 0604 0002 f2ff" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0040: 0000 0001 0a01 0164 f2ff 0000 0004 0a01" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0050: 0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0030: 0000 0001 0806 0001 0800 0604 0002 f2ff" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0040: 0000 0001 0a01 0164 f2ff 0000 0004 0a01" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0050: 0101" 2>&1 1>/dev/null]) - - dnl Because tcpdump might not be able to parse erspan headers, we check icmp echo reply - dnl by packet length. --AT_FAIL_IF([cat p0.pcap | egrep "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 126" 2>&1 1>/dev/null]) -+AT_FAIL_IF([cat p0.pcap | grep -E "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 126" 2>&1 1>/dev/null]) - - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000308004500009287e14000402f57b8ac1f0101ac1f0164100088be0000000520000001144cd5a400008078f2ff00000001f2ff0000000408004500005c38d640004001eb640a0101010a01016408005e57585f0001df6c6b5b0000000045bc050000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f actions=normal" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 126" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "IP 172.31.1.100 > 172.31.1.1: GREv0,.* length 126" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -974,15 +974,15 @@ dnl Okay, now send raw arp request and i - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000386dd60008531003a2f40fc000100000000000000000000000001fc000100000000000000000000000100100088be000000051000007b00000007fffffffffffff2ff0000000408060001080006040001f2ff000000040a0101010000000000000a010164 actions=normal" - - dnl Check arp reply. --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0040: 0000 0001 0806 0001 0800 0604 0002 f2ff" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0050: 0000 0001 0a01 0164 f2ff 0000 0004 0a01" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0060: 0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0040: 0000 0001 0806 0001 0800 0604 0002 f2ff" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0050: 0000 0001 0a01 0164 f2ff 0000 0004 0a01" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0060: 0101" 2>&1 1>/dev/null]) - --AT_FAIL_IF([cat p0.pcap | egrep "IP6 fc00:100::100 > fc00:100::1: GREv0,.* length 114" 2>&1 1>/dev/null]) -+AT_FAIL_IF([cat p0.pcap | grep -E "IP6 fc00:100::100 > fc00:100::1: GREv0,.* length 114" 2>&1 1>/dev/null]) - - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000386dd60008531007a3c40fc000100000000000000000000000001fc0001000000000000000000000001002f00040104010100100088be000000061000407b00000007f2ff00000001f2ff0000000408004500005429b640004001fa8c0a0101010a01016408005c2c7526000118d3685b00000000e4aa020000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 actions=normal" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "IP6 fc00:100::100 > fc00:100::1: GREv0,.* length 114" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "IP6 fc00:100::100 > fc00:100::1: GREv0,.* length 114" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -1029,15 +1029,15 @@ NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 - - dnl Okay, now send raw arp request and icmp echo request. - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000386dd60008531003e2f40fc000100000000000000000000000001fc000100000000000000000000000100100088be0000000620000079af514f9900008070fffffffffffff2ff0000000408060001080006040001f2ff000000040a0101010000000000000a010164 actions=normal" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0040: 0004 f2ff 0000 0001 0806 0001 0800 0604" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0050: 0002 f2ff 0000 0001 0a01 0164 f2ff 0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p0.pcap | egrep "0x0060: 0004 0a01 0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0040: 0004 f2ff 0000 0001 0806 0001 0800 0604" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0050: 0002 f2ff 0000 0001 0a01 0164 f2ff 0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "0x0060: 0004 0a01 0101" 2>&1 1>/dev/null]) - --AT_FAIL_IF([cat p0.pcap | egrep "IP6 fc00:100::100 > fc00:100::1: GREv0, .* length 118" 2>&1 1>/dev/null]) -+AT_FAIL_IF([cat p0.pcap | grep -E "IP6 fc00:100::100 > fc00:100::1: GREv0, .* length 118" 2>&1 1>/dev/null]) - - ovs-ofctl -O OpenFlow13 packet-out br-underlay "in_port=1 packet=f2ff00000002f2ff0000000386dd60008531007e3c40fc000100000000000000000000000001fc0001000000000000000000000001002f00040104010100100088be0000000720004079af514f9b00008070f2ff00000001f2ff00000004080045000054ffcb4000400124770a0101010a0101640800419e23ac000112d7685b000000004caf0c0000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637 actions=normal" - --OVS_WAIT_UNTIL([cat p0.pcap | egrep "IP6 fc00:100::100 > fc00:100::1: GREv0, .* length 118" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p0.pcap | grep -E "IP6 fc00:100::100 > fc00:100::1: GREv0, .* length 118" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -1829,10 +1829,10 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) - - dnl Check the expected mpls encapsulated packet on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8847 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8847 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -1861,10 +1861,10 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) - - dnl Check the expected mpls encapsulated packet on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8847 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8847 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -1894,10 +1894,10 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) - - dnl Check the expected mpls encapsulated packet on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8848 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8848 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -1926,10 +1926,10 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) - - dnl Check the expected mpls encapsulated packet on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8848 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *0000 *0000 *0002 *0000 *0000 *0001 *8848 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *2140 *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *4500 *0054 *0344 *4000 *4001 *2161 *0a01 *0101" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0a01 *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -1960,13 +1960,13 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 00 00 00 00 00 02 00 00 00 00 00 01 88 47 00 00 21 40 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) - - dnl Check the expected decapsulated on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800 *4500" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *0054 *0344 *4000 *4001 *2161 *0a01 *0101 *0a01" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0000 *500b *0200 *0000 *0000 *1011 *1213 *1415" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0040: *1617 *1819 *1a1b *1c1d *1e1f *2021 *2223 *2425" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0050: *2627 *2829 *2a2b *2c2d *2e2f *3031 *3233 *3435" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0060: *3637" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800 *4500" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0054 *0344 *4000 *4001 *2161 *0a01 *0101 *0a01" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0000 *500b *0200 *0000 *0000 *1011 *1213 *1415" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *1617 *1819 *1a1b *1c1d *1e1f *2021 *2223 *2425" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *2627 *2829 *2a2b *2c2d *2e2f *3031 *3233 *3435" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0060: *3637" 2>&1 1>/dev/null]) - - - OVS_TRAFFIC_VSWITCHD_STOP -@@ -1997,13 +1997,13 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 00 00 00 00 00 02 00 00 00 00 00 01 88 47 00 00 21 40 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) - - dnl Check the expected decapsulated on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800 *4500" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *0054 *0344 *4000 *4001 *2161 *0a01 *0101 *0a01" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0000 *500b *0200 *0000 *0000 *1011 *1213 *1415" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0040: *1617 *1819 *1a1b *1c1d *1e1f *2021 *2223 *2425" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0050: *2627 *2829 *2a2b *2c2d *2e2f *3031 *3233 *3435" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0060: *3637" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *36b1 *ee7c *0102 *36b1 *ee7c *0103 *0800 *4500" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0054 *0344 *4000 *4001 *2161 *0a01 *0101 *0a01" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0102 *0800 *efac *7ce4 *0003 *5b2c *1f61 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0000 *500b *0200 *0000 *0000 *1011 *1213 *1415" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *1617 *1819 *1a1b *1c1d *1e1f *2021 *2223 *2425" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *2627 *2829 *2a2b *2c2d *2e2f *3031 *3233 *3435" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0060: *3637" 2>&1 1>/dev/null]) - - - OVS_TRAFFIC_VSWITCHD_STOP -@@ -5448,7 +5448,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrac - udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),mark=1 - ]) - --AT_CHECK([tcpdump -v "icmp" -r p0.pcap 2>/dev/null | egrep 'wrong|bad'], [1], [ignore-nolog]) -+AT_CHECK([tcpdump -v "icmp" -r p0.pcap 2>/dev/null | grep -E 'wrong|bad'], [1], [ignore-nolog]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -6198,7 +6198,7 @@ sleep 1 - dnl UDP packets from ns0->ns1 should solicit "destination unreachable" response. - NS_CHECK_EXEC([at_ns0], [bash -c "echo a | nc -6 $NC_EOF_OPT -u fc00::2 1"]) - --AT_CHECK([tcpdump -v "icmp6" -r p0.pcap 2>/dev/null | egrep 'wrong|bad'], [1], [ignore-nolog]) -+AT_CHECK([tcpdump -v "icmp6" -r p0.pcap 2>/dev/null | grep -E 'wrong|bad'], [1], [ignore-nolog]) - - AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl - udp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::240,sport=,dport=) -@@ -7197,12 +7197,12 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) - - dnl Check the expected nsh encapsulated packet on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0fc6" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *0103 *0012 *34ff *1122 *3344 *0000 *0000 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *0000 *0000 *0000 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0fc6" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0103 *0012 *34ff *1122 *3344 *0000 *0000 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0000 *0000 *0000 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -7229,10 +7229,10 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 00 64 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) - - dnl Check the expected de-capsulated TCP packet on the egress interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *f200 *0000 *0002 *f200 *0000 *0001 *0800 *4500" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *0028 *0001 *0000 *4006 *b013 *c0a8 *000a *0a00" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *000a *0400 *0800 *0000 *00c8 *0000 *0000 *5002" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *2000 *b85e *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f200 *0000 *0002 *f200 *0000 *0001 *0800 *4500" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0028 *0001 *0000 *4006 *b013 *c0a8 *000a *0a00" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *000a *0400 *0800 *0000 *00c8 *0000 *0000 *5002" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *2000 *b85e *0000" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -7262,12 +7262,12 @@ dnl p1(at_ns1) interface - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) - - dnl Check the expected NSH packet with new fields in the header --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000* 0001 *894f *01c6" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *0103 *0001 *0104 *100f *0e0d *0c0b *0a09 *0807" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *0605 *0403 *0201 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000* 0001 *894f *01c6" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0103 *0001 *0104 *100f *0e0d *0c0b *0a09 *0807" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0605 *0403 *0201 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -@@ -7296,23 +7296,23 @@ dnl First send packet from at_ns0 --> OV - NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 02 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) - - dnl Check for the above packet on p1 interface --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0206" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0010: *0103 *0001 *0002 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p1.pcap | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0206" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0010: *0103 *0001 *0002 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p1.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) - - dnl Send the second packet from at_ns1 --> OVS with SPI=0x100 and SI=1 - NS_CHECK_EXEC([at_ns1], [$PYTHON3 $srcdir/sendpkt.py p1 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 01 c6 01 03 00 01 00 01 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) - - dnl Check for the above packet on p2 interface --OVS_WAIT_UNTIL([cat p2.pcap | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *01c6" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p2.pcap | egrep "0x0010: *0103 *0001 *0001 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p2.pcap | egrep "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p2.pcap | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p2.pcap | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) --OVS_WAIT_UNTIL([cat p2.pcap | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *01c6" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0010: *0103 *0001 *0001 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) -+OVS_WAIT_UNTIL([cat p2.pcap | grep -E "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) - - OVS_TRAFFIC_VSWITCHD_STOP - AT_CLEANUP -Index: openvswitch-2.17.2/tests/tunnel-push-pop.at -=================================================================== ---- openvswitch-2.17.2.orig/tests/tunnel-push-pop.at -+++ openvswitch-2.17.2/tests/tunnel-push-pop.at -@@ -740,14 +740,14 @@ dnl Output to tunnel from a int-br inter - dnl Checking that the packet arrived and it was correctly encapsulated. - AT_CHECK([ovs-ofctl add-flow int-br "in_port=LOCAL,actions=debug_slow,output:2"]) - AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"]) --OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}4" | wc -l` -ge 1]) -+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep -E "${encap}${packet}4" | wc -l` -ge 1]) - dnl Sending again to exercise the non-miss upcall path. - AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"]) --OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}4" | wc -l` -ge 2]) -+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep -E "${encap}${packet}4" | wc -l` -ge 2]) - - dnl Output to tunnel from the controller. - AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out int-br CONTROLLER "debug_slow,output:2" "${packet}5"]) --OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}5" | wc -l` -ge 1]) -+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep -E "${encap}${packet}5" | wc -l` -ge 1]) - - dnl Datapath actions should not have tunnel push action. - AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q tnl_push], [1]) diff --git a/openvswitch-2.17.2.tar.gz b/openvswitch-2.17.2.tar.gz deleted file mode 100644 index da901de..0000000 --- a/openvswitch-2.17.2.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6a2e0db42badb8cbcaf7f3bebd5b5e9a2701319df1d04294e9a7a79e94504d69 -size 7955727 diff --git a/openvswitch-3.1.0.tar.gz b/openvswitch-3.1.0.tar.gz new file mode 100644 index 0000000..87f0ea7 --- /dev/null +++ b/openvswitch-3.1.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bdda56970e324107b7a7c9f178d928024bd6603cfd86f71959bec0ed0d1c4bb +size 7836227 diff --git a/openvswitch.changes b/openvswitch.changes index ce7ff6b..eaa540b 100644 --- a/openvswitch.changes +++ b/openvswitch.changes @@ -1,3 +1,60 @@ +------------------------------------------------------------------- +Wed Apr 5 21:14:59 UTC 2023 - Duraisankar P + +- Update OVS version to v3.1.0 and OVN version to v23.03.0 + Some of the features are, + - ovs-vswitchd now detects changes in CPU affinity and adjusts the number + of handler and revalidator threads if necessary. + - AF_XDP: + * Added support for building with libxdp and libbpf >= 0.7. + * Support for AF_XDP is now enabled by default if all dependencies are + available at the build time. Use --disable-afxdp to disable. + Use --enable-afxdp to fail the build if dependencies are not present. + - ovs-appctl: + * "ovs-appctl ofproto/trace" command can now display port names with the + "--names" option. + - OVSDB-IDL: + * Add the support to specify the persistent uuid for row insert in both + C and Python IDLs. + - Windows: + * Conntrack IPv6 fragment support. + - DPDK: + * Add support for DPDK 22.11.1. + - For the QoS max-rate and STP/RSTP path-cost configuration OVS now assumes + 10 Gbps link speed by default in case the actual link speed cannot be + determined. Previously it was 10 Mbps. Values can still be overridden + by specifying 'max-rate' or '[r]stp-path-cost' accordingly. + - OpenFlow: + * New OpenFlow extension NXT_CT_FLUSH to flush connections matching + the specified fields. + - ovs-ctl: + * New option '--dump-hugepages' to include hugepages in core dumps. This + can assist with postmortem analysis involving DPDK, but may also produce + significantly larger core dump files. + - ovs-dpctl and 'ovs-appctl dpctl/' commands: + * 'flush-conntrack' is now capable of handling partial 5-tuple, + with additional optional parameter to specify the reply direction. + - ovs-ofctl: + * New command 'flush-conntrack' that accepts zone and 5-tuple (or partial + 5-tuple) for both directions. + - Support for travis-ci.org based continuous integration builds has been + dropped. + - Userspace datapath: + * Add '-secs' argument to appctl 'dpif-netdev/pmd-rxq-show' to show + the pmd usage of an Rx queue over a configurable time period. + * Add new experimental PMD load based sleeping feature. PMD threads can + request to sleep up to a user configured 'pmd-maxsleep' value under + low load conditions. + -For more details, check + https://github.com/openvswitch/ovs/blob/v3.1.0/NEWS + -Includes secrity fix for CVE-2022-4338 (bsc#1206580) and CVE-2022-4337 (bsc#1206581) +- OVN package is not included as new version with API chnages are not yet released. +- Removed upstreamed patches, + * 0001-Replace-deprecated-var-run-with-run.patch + * openvswitch-CVE-2021-36980.patch +- Added ovsb tool install patch, + * install-ovsdb-tools.patch + ------------------------------------------------------------------- Thu Sep 29 11:58:47 UTC 2022 - Dirk Müller diff --git a/openvswitch.spec b/openvswitch.spec index 92920e8..4536499 100644 --- a/openvswitch.spec +++ b/openvswitch.spec @@ -1,7 +1,7 @@ # # spec file for package openvswitch # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,24 +18,40 @@ %define skip_python2 1 +%define ovs_lname libopenvswitch-3_1-0 +%define ovn_lname libovn-23_03-0 +%define ovs_version 3.1.0 +%define ovn_version 23.03.0 +%define ovs_dir ovs-%{ovs_version} +%define ovn_dir ovn-%{ovn_version} %define rpmstate %{_rundir}/openvswitch-rpm-state- +%define _dpdkv 22.11.1 +%define name_tag ${nil} #Compat macro for new _fillupdir macro introduced in Nov 2017 %if ! %{defined _fillupdir} %define _fillupdir %{_localstatedir}/adm/fillup-templates %endif %ifarch aarch64 x86_64 ppc64le +%if 0%{?suse_version} +# DPDK enabled only SUSE/openSUSE %bcond_without dpdk %else +# DPDK disabled elsewhere even if supported by the architecture. +%bcond_with dpdk +%endif +%else # No DPDK support on these architectures %bcond_with dpdk %endif # The testsuite is somewhat fragile for continuous testing in OBS -%bcond_without check +# but keep it here as an option +%bcond_with check # Disable building the external kernel datapath by default %bcond_with kmp -%define lname libopenvswitch-2_17-0 +# Disable building with AF_XDP support, specify '--without afxdp' when building +%bcond_with afxdp Name: openvswitch -Version: 2.17.2 +Version: %{ovs_version} Release: 0 Summary: A multilayer virtual network switch # All code is Apache-2.0 except @@ -43,31 +59,27 @@ Summary: A multilayer virtual network switch # - utilities/bugtool which is LGPL-2.1 License: Apache-2.0 AND LGPL-2.1-only AND SISSL Group: Productivity/Networking/System -URL: https://www.openvswitch.org/ -Source0: https://www.openvswitch.org/releases/openvswitch-%{version}.tar.gz +URL: http://openvswitch.org/ +Source0: http://openvswitch.org/releases/openvswitch-%{version}.tar.gz +Source1: https://github.com/ovn-org/ovn/archive/v%{ovn_version}.tar.gz#/ovn-%{ovn_version}.tar.gz Source2: preamble Source89: Module.supported.updates Source99: openvswitch-rpmlintrc +# OVS patches # PATCH-FIX-OPENSUSE: Use-strongswan-for-openvswitch-ipsec-service.patch -Patch0: Use-strongswan-for-openvswitch-ipsec-service.patch -# PATCH-FIX-OPENSUSE: Run-openvswitch-as-openvswitch-openvswitch.patch -Patch1: Run-openvswitch-as-openvswitch-openvswitch.patch -# PATCH-FIX-OPENSUSE: Don-t-change-permissions-of-dev-hugepages.patch -Patch2: Don-t-change-permissions-of-dev-hugepages.patch -# PATCH-FIX-OPENSUSE: Use-double-hash-for-OVS_USER_ID-comment.patch -Patch3: Use-double-hash-for-OVS_USER_ID-comment.patch +Patch0: 0001-Use-strongswan-for-openvswitch-ipsec-service.patch +# PATCH-FIX-OPENSUSE: 0001-Run-openvswitch-as-openvswitch-openvswitch.patch +Patch1: 0001-Run-openvswitch-as-openvswitch-openvswitch.patch +# PATCH-FIX-OPENSUSE: 0001-Don-t-change-permissions-of-dev-hugepages.patch +Patch2: 0001-Don-t-change-permissions-of-dev-hugepages.patch +# PATCH-FIX-OPENSUSE: 0001-Use-double-hash-for-OVS_USER_ID-comment.patch +Patch3: 0001-Use-double-hash-for-OVS_USER_ID-comment.patch # PATCH-FEATURE-UPSTREAM install-ovsdb-tools.patch -- Install some tools required for building OVN Patch4: install-ovsdb-tools.patch -Patch5: 0001-openvswitch-merge-compiler.h-files-into-one-file.patch -Patch6: 0002-build-Seperated-common-used-headers.patch -Patch7: openvswitch-2.17.2-Fix-tests-with-GNU-grep-3.8.patch -Patch8: a77ad9693c8b49055389559187fe74eddb619746.patch -Patch9: 0001-m4-Test-avx512-for-x86-only.patch -# Python subpackage -BuildRequires: %{python_module devel} -BuildRequires: %{python_module setuptools} -BuildRequires: python-rpm-macros -# Main package +#OVN patches +# PATCH-FIX-OPENSUSE: 0001-Run-ovn-as-openvswitch-openvswitch.patch +Patch20: 0001-Run-ovn-as-openvswitch-openvswitch.patch +# CVE-2021-36980 [bsc#1188524], use-after-free in decode_NXAST_RAW_ENCAP BuildRequires: autoconf BuildRequires: automake BuildRequires: fdupes @@ -77,15 +89,13 @@ BuildRequires: make BuildRequires: pkgconfig BuildRequires: python3 BuildRequires: python3-Sphinx +BuildRequires: python3-devel BuildRequires: unbound-devel BuildRequires: pkgconfig(libcap-ng) BuildRequires: pkgconfig(openssl) Requires: modutils # ovs-ctl / ovs-pki use /usr/bin/uuidgen: Requires: util-linux -Requires(post): %fillup_prereq -Requires(pre): shadow -Suggests: logrotate Provides: openvswitch-common = %{version} Obsoletes: openvswitch-common < 2.7.0 Provides: openvswitch-controller = %{version} @@ -98,7 +108,23 @@ Provides: %{name}-switch = %{version} Obsoletes: %{name}-dpdk < 2.7.0 Obsoletes: %{name}-dpdk-switch < 2.7.0 Obsoletes: %{name}-switch < 2.7.0 +%if 0%{?suse_version} +BuildRequires: libopenssl-devel +BuildRequires: python-rpm-macros +Requires(post): %fillup_prereq +Requires(pre): shadow +Suggests: logrotate %{?systemd_ordering} +%else +BuildRequires: environment-modules +BuildRequires: openssl-devel +BuildRequires: python3-rpm-macros +BuildRequires: systemd-units +Requires(post): systemd-units +Requires(postun):systemd-units +Requires(pre): shadow-utils +Requires(preun):systemd-units +%endif # Needed by the testsuite %if %{with check} BuildRequires: procps @@ -110,22 +136,12 @@ Suggests: openvswitch-kmp # We need to be a bit strict with the dpdk version since # it's very possible for DPDK to change it's API between # releases. -BuildRequires: dpdk-devel <= 21.12 -BuildRequires: dpdk-devel >= 20.11.0 +BuildRequires: dpdk-devel >= %{_dpdkv} BuildRequires: libmnl-devel BuildRequires: libnuma-devel BuildRequires: libpcap-devel BuildRequires: rdma-core-devel %endif -%if 0%{?suse_version} >= 1550 -# TW: generate subpackages for every python3 flavor -%define python_subpackage_only 1 -%python_subpackages -%else -%define python_sitelib %python3_sitelib -%define python_sitelib %{python3_sitelib} -%define python_files() -n python3-%{**} -%endif %description Open vSwitch is a multilayer virtual network Ethernet switch. It is @@ -147,12 +163,16 @@ BuildRequires: %{kernel_module_package_buildreqs} Kernel modules supporting the openvswitch datapath. %endif -%package -n %{lname} +%package -n %{ovs_lname} Summary: Open vSwitch core libraries License: Apache-2.0 Group: System/Libraries +%if %{with dpdk} +Requires: dpdk >= %{_dpdkv} +Requires: libdpdk-23 >= %{_dpdkv} +%endif -%description -n %{lname} +%description -n %{ovs_lname} Contains the shared libraries used by Open vSwitch and any eventual extensions. %package doc @@ -168,7 +188,7 @@ Contains additional documentation for the Open vSwitch. Summary: Development files for Open vSwitch License: Apache-2.0 Group: Development/Libraries/C and C++ -Requires: %{lname} = %{version} +Requires: %{ovs_lname} = %{version} # Required for ovsdb-ildc Requires: python3-ovs = %{version} Provides: %{name}-dpdk-devel = %{version} @@ -221,6 +241,19 @@ Requires: strongswan %description ipsec This package provides IPsec tunneling support for OVS tunnels. +%package -n python3-ovs +Summary: Python3 bindings for Open vSwitch +License: Apache-2.0 +Group: Productivity/Networking/System +Requires: %{ovs_lname} = %{version} +Requires: python3 +Requires: python3-sortedcontainers +Provides: python3-%{name} = %{version} +Obsoletes: python3-%{name} < 2.10.1 + +%description -n python3-ovs +This package contains the Python3 bindings for Open vSwitch database. + %package test Summary: Open vSwitch test package License: Apache-2.0 @@ -238,56 +271,183 @@ Open vSwitch is a software-based Ethernet switch. This package contains utilities that are useful to diagnose performance and connectivity issues in Open vSwitch setup. -%if 0%{?python_subpackage_only} -%package -n python-ovs -Summary: Python bindings for Open vSwitch +%package -n ovn +Version: %{ovn_version} +Release: 0 +Summary: Open Virtual Network diagnostic utilities License: Apache-2.0 Group: Productivity/Networking/System -Requires: %{lname} = %{version} -Requires: python-sortedcontainers - -%description -n python-ovs -This package contains the Python3 bindings for Open vSwitch database. -%else - -%package -n python3-ovs -Summary: Python bindings for Open vSwitch -License: Apache-2.0 -Group: Productivity/Networking/System -Requires: %{lname} = %{version} -Requires: python-sortedcontainers - -%description -n python3-ovs -This package contains the Python3 bindings for Open vSwitch database. +URL: http://ovn.org/ +Requires: %{name} = %{ovs_version} +# openvswitch-ovn has been split into openvswitch-ovn-{central,common,docker,host,vtep} +Provides: %{name}-dpdk-ovn = %{ovn_version} +Provides: %{name}-ovn = %{ovn_version} +Provides: %{name}-ovn-common = %{ovn_version} +Obsoletes: %{name}-dpdk-ovn < 2.7.0 +Obsoletes: %{name}-ovn < 2.7.0 +Obsoletes: %{name}-ovn-common < 2.13.0 +%if 0%{?suse_version} +Suggests: logrotate %endif +%description -n ovn +OVN, the Open Virtual Network, is a system to support virtual network +abstraction. OVN complements the existing capabilities of OVS to add +native support for virtual network abstractions, such as virtual L2 and L3 +overlays and security groups. + +%package -n ovn-central +Version: %{ovn_version} +Release: 0 +Summary: Open Virtual Network support for Open vSwitch +License: Apache-2.0 +Group: Productivity/Networking/System +URL: http://ovn.org/ +Requires: %{name} = %{ovs_version} +Requires: ovn = %{ovn_version} +# openvswitch-ovn has been split into openvswitch-ovn-{central,common,docker,host,vtep} +Provides: %{name}-dpdk-ovn:%{_bindir}/ovn-northd +Provides: %{name}-ovn-central = %{ovn_version} +Provides: %{name}-ovn:%{_bindir}/ovn-northd +Obsoletes: %{name}-ovn-central < 2.13.0 + +%description -n ovn-central +This subpackage contains the OVN database and northbound daemon. + +%package -n ovn-host +Version: %{ovn_version} +Release: 0 +Summary: Open Virtual Network support for Open vSwitch +License: Apache-2.0 +Group: Productivity/Networking/System +URL: http://ovn.org/ +Requires: %{name} = %{ovs_version} +Requires: ovn = %{ovn_version} +# openvswitch-ovn has been split into openvswitch-ovn-{central,common,docker,host,vtep} +Provides: %{name}-dpdk-ovn:%{_bindir}/ovn-controller +Provides: %{name}-ovn-host = %{ovn_version} +Provides: %{name}-ovn:%{_bindir}/ovn-controller +Obsoletes: %{name}-ovn-host < 2.13.0 + +%description -n ovn-host +This subpackage contains the OVN host controller. + +%package -n ovn-vtep +Version: %{ovn_version} +Release: 0 +Summary: Open Virtual Network VTEP controller for Open vSwitch +License: Apache-2.0 +Group: Productivity/Networking/System +URL: http://ovn.org/ +Requires: %{name} = %{ovs_version} +Requires: ovn = %{ovn_version} +# openvswitch-ovn has been split into openvswitch-ovn-{central,common,docker,host,vtep} +Provides: %{name}-dpdk-ovn:%{_bindir}/ovn-controller-vtep +Provides: %{name}-ovn-vtep = %{ovn_version} +Provides: %{name}-ovn:%{_bindir}/ovn-controller-vtep +Obsoletes: %{name}-ovn-vtep < 2.13.0 + +%description -n ovn-vtep +This subpackage contains the OVN VTEP (VXLAN Tunnel Endpoint) controller. + +%package -n ovn-docker +Version: %{ovn_version} +Release: 0 +Summary: Docker network plugins for OVN +License: Apache-2.0 +Group: Productivity/Networking/System +URL: http://ovn.org/ +Requires: %{name} = %{ovs_version} +Requires: ovn = %{ovn_version} +Requires: python3-openvswitch = %{ovs_version} +# openvswitch-ovn has been split into openvswitch-ovn-{central,common,docker,host,vtep} +Provides: %{name}-dpdk-ovn:%{_bindir}/ovn-docker-overlay-driver +Provides: %{name}-ovn-docker = %{ovn_version} +Provides: %{name}-ovn:%{_bindir}/ovn-docker-overlay-driver +Obsoletes: %{name}-ovn-docker < 2.13.0 + +%description -n ovn-docker +This subpackage contains the OVN Docker network plugins. + +%package -n ovn-doc +Version: %{ovn_version} +Release: 0 +Summary: Open Virtual Network Documentation +License: Apache-2.0 +Group: System/Libraries +BuildArch: noarch + +%description -n ovn-doc +Contains additional documentation for OVN. + +%package -n %{ovn_lname} +Version: %{ovn_version} +Release: 0 +Summary: Open Virtual Network core libraries +License: Apache-2.0 +Group: System/Libraries + +%description -n %{ovn_lname} +This subpackage contains the OVN shared libraries. + +%package -n ovn-devel +Version: %{ovn_version} +Release: 0 +Summary: Development files for Open Virtual Network +License: Apache-2.0 +Group: Development/Libraries/C and C++ +Requires: %{ovn_lname} = %{ovn_version} +# ovn-devel was split form openvswitch-devel +Provides: %{name}-devel:%{_includedir}/ovn + +%description -n ovn-devel +Devel libraries and headers for Open Virtual Network. + %prep -%autosetup -p1 +%setup -q -n %{name}-%{ovs_version} -a 1 +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +cd %{ovn_dir} +%patch20 -p1 %build -autoreconf -fi +mkdir %ovs_dir +# We build both OVS and OVN. OVN is already on its own subdir ovn_dir. +# Move OVS sources to ovs_dir +find $PWD -maxdepth 1 ! -path $PWD ! -name %ovs_dir -a ! -name %ovn_dir -exec mv -t %ovs_dir {} + + +# Init OVS config. +pushd %ovs_dir +# only call boot.sh for distros with autoconf >= 2.64 +bash -x boot.sh +popd # Build kernel modules if needed. %if %{with kmp} mkdir kmp - export EXTRA_CFLAGS='-DVERSION=\"%{version}\"' + export EXTRA_CFLAGS='-DVERSION=\"%{ovs_version}\"' for flavor in %{flavors_to_build}; do rm -rf kmp/$flavor - mkdir -p kmp/$flavor + cp -r %ovs_dir kmp/$flavor + cp -a %{SOURCE89} kmp/$flavor/datapath/linux/Module.supported pushd kmp/$flavor - tar -xf "%{SOURCE0}" - cp -a %{SOURCE89} datapath/linux/Module.supported %configure \ --with-logdir=%{_localstatedir}/log/openvswitch \ --with-rundir=%{_rundir}/openvswitch \ --with-linux=%{_prefix}/src/linux-obj/%{_target_cpu}/$flavor \ --with-linux-source=%{_prefix}/src/linux cd datapath/linux - %make_build + make %{?_smp_mflags} popd done %endif +# Build OVS. +pushd %ovs_dir + # This currently has no effect as the @dpdk section has been patched out of the # service file. Run it anyway, in case a new section that we need appears over # time. @@ -301,18 +461,42 @@ python3 build-aux/dpdkstrip.py \ > rhel/usr_lib_systemd_system_ovs-vswitchd.service %configure \ - --disable-static \ - --enable-shared \ - --enable-libcapng \ - --enable-ssl \ + --disable-static \ + --enable-shared \ + --enable-libcapng \ + --enable-ssl \ %if %{with dpdk} - --with-dpdk=shared \ + --with-dpdk=shared \ %endif - --with-dbdir=%{_sharedstatedir}/openvswitch \ - --with-rundir=%{_rundir}/openvswitch \ - --with-logdir=%{_localstatedir}/log/openvswitch \ - --with-pkidir=%{_sharedstatedir}/openvswitch/pki \ - PYTHON3=%{_bindir}/python3 +%if %{with afxdp} + --enable-afxdp \ +%else + --disable-afxdp \ +%endif + --with-dbdir=%{_sharedstatedir}/openvswitch \ + --with-rundir=%{_rundir}/openvswitch \ + --with-logdir=%{_localstatedir}/log/openvswitch \ + --with-pkidir=%{_sharedstatedir}/openvswitch/pki \ + PYTHON3=%{_bindir}/python3 +%make_build +popd + +# Build OVN. +pushd %ovn_dir + +bash -x boot.sh +%configure \ + --with-ovs-source=../%{ovs_dir} \ + --disable-static \ + --enable-shared \ + --enable-libcapng \ + --enable-ssl \ + --with-dbdir=%{_sharedstatedir}/ovn \ + --with-rundir=%{_rundir}/ovn \ + --with-logdir=%{_localstatedir}/log/ovn \ + --with-pkidir=%{_sharedstatedir}/openvswitch/pki \ + PYTHON3=%{_bindir}/python3 \ + LDFLAGS=-L../%{ovs_dir}/lib/.libs %make_build %check @@ -322,17 +506,28 @@ export OVS_RESOLV_CONF=$(pwd)/resolv.conf mv python/build python/pb ln -s _build.tmp python/build +pushd %ovs_dir # Recheck tests before we declare them broken. If that fails, dump # the log and exit. >2.5.0 uses the RECHECK env variable so this # needs to be taken into consideration for future releases. -if ! make check-am TESTSUITEFLAGS="%{?_smp_mflags}" && - ! make check-am TESTSUITEFLAGS='--recheck'; then +if ! make check TESTSUITEFLAGS="%{?_smp_mflags}" && + ! make check RECHECK=yes; then cat tests/testsuite.log exit 1 fi +popd + +pushd $ovn_dir +if ! make check TESTSUITEFLAGS="%{?_smp_mflags}" && + ! make check RECHECK=yes; then + cat tests/testsuite.log + exit 1 +fi +popd %endif %install + # Intall kernel modules. %if %{with kmp} export NO_BRP_STALE_LINK_ERROR=yes @@ -346,16 +541,54 @@ for flavor in %{flavors_to_build}; do done %endif -%make_install -# Remove static libraries and libtool files -rm -f %{buildroot}%{_libdir}/*.{l,}a +# Install OVS dist files on temp buildroot. +mkdir -p buildroot/ovs +pushd %ovs_dir +%make_install DESTDIR=$(pwd)/../buildroot/ovs +popd -# Fix installation path -mkdir -p %{buildroot}/%{_datadir}/bash-completion/completions/ -mv %{buildroot}/%{_sysconfdir}/bash_completion.d/ovs-* %{buildroot}/%{_datadir}/bash-completion/completions/ -chmod 0644 %{buildroot}/%{_datadir}/bash-completion/completions/* +# Clean up OVS files +rm -f buildroot/ovs%{_libdir}/*.a +rm -f buildroot/ovs%{_libdir}/*.la + +# Install OVN dist files on temp build root. +mkdir -p buildroot/ovn +pushd %ovn_dir +%make_install DESTDIR=$(pwd)/../buildroot/ovn +popd + +# Clean up OVN files +rm -f buildroot/ovn%{_datadir}/ovn/scripts/ovs* +rm -rf buildroot/ovn%{_datadir}/ovn/bugtool-plugins +rm -f buildroot/ovn%{_libdir}/*.a +rm -f buildroot/ovn%{_libdir}/*.la + +# Remove known OVS dupes from OVN. +rm -f buildroot/ovn%{_mandir}/man5/ovs* +rm -f buildroot/ovn%{_mandir}/man7/ovs* + +# Verify no duplicates and move dist files to real buildroot +dupes=$(find buildroot -mindepth 2 -type f -printf '%p\n' | cut -d'/' -f3- | sort | uniq -c | grep -Ev "^ *1 " || true) +[ -n "$dupes" ] && exit 1 +cp -an buildroot/ovn/* %{buildroot}/ +cp -an buildroot/ovs/* %{buildroot}/ + +# Install OVS additional files +pushd %ovs_dir + +# Install extra headers not included with 'make install' +copy_headers() { + src=$1 + dst=%{buildroot}/$2 + install -d -m 0755 $dst + install -m 0644 $src/*.h $dst +} +copy_headers include/sparse %{_includedir}/openvswitch/sparse +copy_headers include/sparse/arpa %{_includedir}/openvswitch/sparse/arpa +copy_headers include/sparse/netinet %{_includedir}/openvswitch/sparse/netinet +copy_headers include/sparse/sys %{_includedir}/openvswitch/sparse/sys +copy_headers lib %{_includedir}/openvswitch/lib -# Install systemd files for service in openvswitch \ ovsdb-server \ ovs-vswitchd \ @@ -366,9 +599,36 @@ for service in openvswitch \ ln -sf %{_sbindir}/service %{buildroot}%{_sbindir}/rc${service} done +# This changes group ownership of any vfio device to 'hugetlbfs' through udev. +# That's probably not the most appropriate name for such a group and also +# should probably be coordinated system wide. +#%%if %%{with dpdk} +# install -p -D -m 0644 rhel/usr_lib_udev_rules.d_91-vfio.rules \ +# %%{buildroot}%%{_prefix}/lib/udev/rules.d/91-vfio.rules +#%%endif + +%if 0%{?suse_version} install -D -m 644 rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template \ %{buildroot}%{_fillupdir}/sysconfig.openvswitch +# Fix installation path +mkdir -p %{buildroot}/%{_datadir}/bash-completion/completions/ +mv %{buildroot}/%{_sysconfdir}/bash_completion.d/ovs-* %{buildroot}/%{_datadir}/bash-completion/completions/ +chmod 0644 %{buildroot}/%{_datadir}/bash-completion/completions/* + +# fixing W: # interpreter +find %{buildroot}/%{_datadir}/openvswitch/scripts/ -name "*.py" -exec sed -i 's|env python|python|' \{\} + + +%else +install -D -m 644 rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template \ + %{buildroot}%{_sysconfdir}/sysconfig/openvswitch +install -d -m 0755 %{buildroot}/%{_sysconfdir}/sysconfig/network-scripts/ +install -p -m 0755 rhel/etc_sysconfig_network-scripts_ifdown-ovs \ + %{buildroot}%{_sysconfdir}/sysconfig/network-scripts/ifdown-ovs +install -p -m 0755 rhel/etc_sysconfig_network-scripts_ifup-ovs \ + %{buildroot}%{_sysconfdir}/sysconfig/network-scripts/ifup-ovs +%endif + install -d -m 0755 %{buildroot}/%{_rundir}/openvswitch install -d -m 0755 %{buildroot}%{_sysconfdir}/logrotate.d install -d -m 0755 %{buildroot}%{_localstatedir}/log/openvswitch @@ -387,33 +647,81 @@ cp -r Documentation/* %{buildroot}%{_docdir}/%{name} rm -rf %{buildroot}%{_docdir}/%{name}/_build rm %{buildroot}%{_docdir}/%{name}/automake.mk rm %{buildroot}%{_docdir}/%{name}/conf.py +popd -# Python subpackage -# Install python tests package +# Tests mkdir -p %{buildroot}%{python3_sitelib} cp -a %{buildroot}%{_datadir}/openvswitch/python/ovstest \ - %{buildroot}%{python3_sitelib} -# Remove non standard location python package + %{buildroot}%{python3_sitelib} + +# Python subpackage +# Build on a temporary directory. +mkdir python3-ovs && pushd $_ +# Some build files are in sources while others are generated directly on +# buildroot as part of make_install (dirs.py). Copy them first. +cp -an ../%{ovs_dir}/python/* $(pwd)/ rm -rf %{buildroot}%{_datadir}/openvswitch/python -# Install python package, some files are generated by make install -# make sure dirs.py is freshly generated -rm -f python/ovs/dirs.py -make python/ovs/dirs.py -pushd python export LDFLAGS="${LDFLAGS} -L %{buildroot}%{_libdir}" -export CPPFLAGS="-I %{buildroot}%{_includedir} -I %{buildroot}%{_includedir}/openvswitch" -%python_build -%python_install -popd -# Currently (version 2.17) the c parser for json is broken on 32bit (int overflow for number parsing) -%ifarch i386 i586 i686 -%python_expand rm -v %{buildroot}%{$python_sitearch}/ovs/_json*.so +export CPPFLAGS="-I ../../include" + +%if 0%{?suse_version} +# SLES +%{python3_build} +%{python3_install} +%else +# RHEL +%py3_build +%py3_install %endif +# Done with OVS additional files. +popd + %python_expand %fdupes %{buildroot}%{$python_sitearch} +# Install OVN aditional files. +pushd %ovn_dir + +for service in ovn-controller \ + ovn-controller-vtep \ + ovn-northd; do + install -D -m 644 rhel/usr_lib_systemd_system_${service}.service \ + %{buildroot}%{_unitdir}/${service}.service + ln -sf %{_sbindir}/service %{buildroot}%{_sbindir}/rc${service} +done + +%if 0%{?suse_version} +install -D -m 644 rhel/usr_share_ovn_scripts_systemd_sysconfig.template \ + %{buildroot}%{_fillupdir}/sysconfig.ovn +%else +install -D -m 644 rhel/usr_share_ovn_scripts_systemd_sysconfig.template \ + %{buildroot}%{_sysconfdir}/sysconfig/ovn +%endif + +# firewalld +install -d %{buildroot}%{_prefix}/lib/firewalld/services/ +install -p -m 0644 rhel/usr_lib_firewalld_services_ovn-central-firewall-service.xml \ + %{buildroot}%{_prefix}/lib/firewalld/services/ovn-central-firewall-service.xml +install -p -m 0644 rhel/usr_lib_firewalld_services_ovn-host-firewall-service.xml \ + %{buildroot}%{_prefix}/lib/firewalld/services/ovn-host-firewall-service.xml + +install -p -D -m 0644 rhel/etc_logrotate.d_ovn \ + %{buildroot}%{_sysconfdir}/logrotate.d/ovn +install -d -m 0755 %{buildroot}%{_localstatedir}/log/ovn + +# Copy documentation. +mkdir -p %{buildroot}%{_docdir}/ovn +cp -r Documentation/* %{buildroot}%{_docdir}/ovn +rm -rf %{buildroot}%{_docdir}/ovn/_build +rm %{buildroot}%{_docdir}/ovn/automake.mk +rm %{buildroot}%{_docdir}/ovn/conf.py + +# Done with OVN additional files. +popd %pre -%service_add_pre ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service +%if 0%{?suse_version} + %service_add_pre ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service +%endif if [ "$1" -ge 1 ]; then # Save the "enabled" state across the transition of # ownership of openvswitch.service from openvswitch-switch to @@ -431,16 +739,44 @@ getent passwd openvswitch >/dev/null || \ exit 0 %pre ipsec -%service_add_pre openvswitch-ipsec.service +%if 0%{?suse_version} + %service_add_pre openvswitch-ipsec.service +%endif %preun -%service_del_preun ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service +%if 0%{?suse_version} + %service_del_preun ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service +%else + %if 0%{?systemd_preun:1} + %systemd_preun %{name}.service + %else + # Package install, not upgrade + if [ $1 -eq 0 ]; then + /bin/systemctl --no-reload disable %{name}.service >/dev/null 2>&1 || : + /bin/systemctl stop %{name}.service >/dev/null 2>&1 || : + fi + %endif +%endif %preun ipsec -%service_del_preun openvswitch-ipsec.service +%if 0%{?suse_version} + %service_del_preun openvswitch-ipsec.service +%endif %preun test -%service_del_preun openvswitch-testcontroller +%if 0%{?suse_version} + %service_del_preun openvswitch-testcontroller +%else + %if 0%{?systemd_post:1} + %systemd_preun openvswitch-testcontroller.service + %else + # Package install, not upgrade + if [ $1 -eq 0 ]; then + /bin/systemctl --no-reload disable openvswitch-testcontroller.service >/dev/null 2>&1 || : + /bin/systemctl stop openvswitch-testcontroller.service >/dev/null 2>&1 || : + fi + %endif +%endif %post if [ $1 -eq 1 ]; then @@ -448,12 +784,26 @@ if [ $1 -eq 1 ]; then # configuration is changed on upgrade so use fillup only for new installs. %{?suse_version: %fillup_only -n openvswitch} fi -%service_add_post ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service + +%if 0%{?suse_version} + %service_add_post ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service +%else + %if 0%{?systemd_post:1} + %systemd_post openvswitch.service + %else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi + %endif +%endif %post ipsec -%service_add_post openvswitch-ipsec.service +%if 0%{?suse_version} + %service_add_post openvswitch-ipsec.service +%endif -%post -n %{lname} -p /sbin/ldconfig +%post -n %{ovs_lname} -p /sbin/ldconfig %postun # Do not restart the openvswitch service on package updates. @@ -462,15 +812,34 @@ fi # after an OvS update if no SDN controller is used. Moreover, restaring # the OvS can break remote administration during the update so let the # admin decide when it's the best time for an OvS restart. -%service_del_postun_without_restart ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service +# 5771f476573445710834234a6a9f7bd999a027e7 ("fedora: do not restart the service on a pkg upgrade") +%if 0%{?suse_version} + %service_del_postun_without_restart ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service +%else + %if 0%{?systemd_postun:1} + %systemd_postun openvswitch.service + %else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + %endif +%endif %postun ipsec -%service_del_postun_without_restart openvswitch-ipsec.service +%if 0%{?suse_version} + %service_del_postun_without_restart openvswitch-ipsec.service +%endif %postun test -%service_del_postun_without_restart openvswitch-testcontroller +%if 0%{?suse_version} + %service_del_postun_without_restart openvswitch-testcontroller +%else + %if 0%{?systemd_postun:1} + %systemd_postun openvswitch-testcontroller.service + %else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + %endif +%endif -%postun -n %{lname} -p /sbin/ldconfig +%postun -n %{ovs_lname} -p /sbin/ldconfig %posttrans # Save the "enabled" state across the transition of ownership @@ -526,6 +895,203 @@ EOF fi fi +%pre -n ovn-central +%if 0%{?suse_version} +%service_add_pre ovn-northd.service +%endif +# Save the "enabled" state across the transition of +# ownership of ovn-northd.service from openvswitch-ovn-central to +# ovn-central. +if [ "$1" -ge 1 ]; then + if [ x$(systemctl is-enabled ovn-northd.service 2>/dev/null ||:) = "xenabled" ]; then + touch %{rpmstate}ovn-northd + fi +fi + +%pre -n ovn-host +%if 0%{?suse_version} +%service_add_pre ovn-controller.service +%endif +# Save the "enabled" state across the transition of +# ownership of ovn-controller.service from openvswitch-ovn-host to +# ovn-host. +if [ "$1" -ge 1 ]; then + if [ x$(systemctl is-enabled ovn-controller.service 2>/dev/null ||:) = "xenabled" ]; then + touch %{rpmstate}ovn-controller + fi +fi + +%pre -n ovn-vtep +%if 0%{?suse_version} +%service_add_pre ovn-controller-vtep.service +%endif +# Save the "enabled" state across the transition of +# ownership of ovn-controller-vtep.service from openvswitch-ovn-vtep to +# ovn-vtep. +if [ "$1" -ge 1 ]; then + if [ x$(systemctl is-enabled ovn-controller-vtep.service 2>/dev/null ||:) = "xenabled" ]; then + touch %{rpmstate}ovn-controller-vtep + fi +fi + +%preun -n ovn-central +%if 0%{?suse_version} + %service_del_preun ovn-northd.service +%else + %if 0%{?systemd_preun:1} + %systemd_preun ovn-northd.service + %else + # Package install, not upgrade + if [ $1 -eq 0 ]; then + /bin/systemctl --no-reload disable ovn-northd.service >/dev/null 2>&1 || : + /bin/systemctl stop ovn-northd.service >/dev/null 2>&1 || : + fi + %endif +%endif + +%preun -n ovn-host +%if 0%{?suse_version} + %service_del_preun ovn-controller.service +%else + %if 0%{?systemd_preun:1} + %systemd_preun ovn-controller.service + %else + # Package install, not upgrade + if [ $1 -eq 0 ]; then + /bin/systemctl --no-reload disable ovn-controller.service >/dev/null 2>&1 || : + /bin/systemctl stop ovn-controller.service >/dev/null 2>&1 || : + fi + %endif +%endif + +%preun -n ovn-vtep +%if 0%{?suse_version} + %service_del_preun ovn-controller-vtep.service +%else + %if 0%{?systemd_preun:1} + %systemd_preun ovn-controller-vtep.service + %else + # Package install, not upgrade + if [ $1 -eq 0 ]; then + /bin/systemctl --no-reload disable ovn-controller-vtep.service >/dev/null 2>&1 || : + /bin/systemctl stop ovn-controller-vtep.service >/dev/null 2>&1 || : + fi + %endif +%endif + +%post -n ovn +if [ $1 -eq 1 ]; then + # Follow the upstream strategy that no running openvswitch + # configuration is changed on upgrade so use fillup only for new installs. + %{?suse_version: %fillup_only -n ovn} +fi + +%post -n ovn-central +%if 0%{?suse_version} + %service_add_post ovn-northd.service +%else + %if 0%{?systemd_post:1} + %systemd_post ovn-northd.service + %else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi + %endif +%endif + +%post -n ovn-host +%if 0%{?suse_version} + %service_add_post ovn-controller.service +%else + %if 0%{?systemd_post:1} + %systemd_post ovn-controller.service + %else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi + %endif +%endif + +%post -n ovn-vtep +%if 0%{?suse_version} + %service_add_post ovn-controller-vtep.service +%else + %if 0%{?systemd_post:1} + %systemd_post ovn-controller-vtep.service + %else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi + %endif +%endif + +%post -n %{ovn_lname} -p /sbin/ldconfig + +%postun -n ovn-central +%if 0%{?suse_version} + %service_del_postun_without_restart ovn-northd.service +%else + %if 0%{?systemd_postun:1} + %systemd_postun ovn-northd.service + %else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + %endif +%endif + +%postun -n ovn-host +%if 0%{?suse_version} + %service_del_postun_without_restart ovn-controller.service +%else + %if 0%{?systemd_postun:1} + %systemd_postun ovn-controller.service + %else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + %endif +%endif + +%postun -n ovn-vtep +%if 0%{?suse_version} + %service_del_postun_without_restart ovn-controller-vtep.service +%else + %if 0%{?systemd_postun:1} + %systemd_postun ovn-controller-vtep.service + %else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + %endif +%endif + +%postun -n %{ovn_lname} -p /sbin/ldconfig + +%posttrans -n ovn-central +# Save the "enabled" state across the transition of +# ownership of ovn-northd.service from openvswitch-ovn-central to +# ovn-central. +if [ -e %{rpmstate}ovn-northd ]; then + rm %{rpmstate}ovn-northd + systemctl enable ovn-northd.service +fi + +%posttrans -n ovn-host +# Save the "enabled" state across the transition of +# ownership of ovn-northd.service from openvswitch-ovn-central to +# ovn-central. +if [ -e %{rpmstate}ovn-controller ]; then + rm %{rpmstate}ovn-controller + systemctl enable ovn-controller.service +fi + +%posttrans -n ovn-vtep +# Save the "enabled" state across the transition of +# ownership of ovn-controller.service from openvswitch-ovn-host to +# ovn-host. +if [ -e %{rpmstate}ovn-controller-vtep ]; then + rm %{rpmstate}ovn-controller-vtep + systemctl enable ovn-controller-vtep.service +fi + %files %defattr(-,root,openvswitch, 775) %dir %{_sysconfdir}/openvswitch @@ -535,6 +1101,7 @@ fi # This is no longer the DB path for new installs but we still need this for # upgrades that preserve the old DB path. %ghost %{_sysconfdir}/openvswitch/.conf.db.~lock~ +%defattr(-,root,root) %config(noreplace) %{_sysconfdir}/openvswitch/default.conf %{_bindir}/ovs-appctl %{_bindir}/ovs-docker @@ -550,6 +1117,7 @@ fi %{_sbindir}/ovsdb-server %dir %{_datadir}/openvswitch %dir %{_datadir}/openvswitch/scripts +%dir %{_datadir}/openvswitch/scripts/usdt %{_datadir}/openvswitch/bugtool-plugins %{_datadir}/openvswitch/scripts/ovs-bugtool-* %{_datadir}/openvswitch/scripts/ovs-check-dead-ifs @@ -557,7 +1125,9 @@ fi %{_datadir}/openvswitch/scripts/ovs-kmod-ctl %{_datadir}/openvswitch/scripts/ovs-lib %{_datadir}/openvswitch/scripts/ovs-save +%{_datadir}/openvswitch/scripts/usdt/* %{_datadir}/openvswitch/vswitch.ovsschema +%{_datadir}/openvswitch/local-config.ovsschema %{_mandir}/man1/ovsdb-client.1%{?ext_man} %{_mandir}/man1/ovsdb-server.1%{?ext_man} %{_mandir}/man1/ovsdb-tool.1%{?ext_man} @@ -578,6 +1148,7 @@ fi %{_mandir}/man8/ovs-parse-backtrace.8%{?ext_man} %{_mandir}/man8/ovs-vsctl.8%{?ext_man} %{_mandir}/man8/ovs-vswitchd.8%{?ext_man} +%{_mandir}/man5/ovsdb.local-config.5.gz %config(noreplace) %{_sysconfdir}/logrotate.d/openvswitch %{_sbindir}/rcovsdb-server %{_sbindir}/rcovs-vswitchd @@ -587,14 +1158,22 @@ fi %{_unitdir}/ovs-vswitchd.service %{_unitdir}/ovsdb-server.service %{_unitdir}/ovs-delete-transient-ports.service +%if 0%{?suse_version} %{_fillupdir}/sysconfig.openvswitch %{_datadir}/bash-completion/completions/ovs-appctl-bashcomp.bash %{_datadir}/bash-completion/completions/ovs-vsctl-bashcomp.bash +%else +%config(noreplace) %{_sysconfdir}/sysconfig/openvswitch +%{_sysconfdir}/bash_completion.d/ovs-appctl-bashcomp.bash +%{_sysconfdir}/bash_completion.d/ovs-vsctl-bashcomp.bash +%{_sysconfdir}/sysconfig/network-scripts/ifup-ovs +%{_sysconfdir}/sysconfig/network-scripts/ifdown-ovs +%endif %ghost %attr(755,root,root) %{_rundir}/openvswitch %ghost %attr(644,root,root) %{_rundir}/openvswitch.useropts %exclude %{_docdir}/%{name} -%doc AUTHORS.rst CONTRIBUTING.rst NEWS README.rst -%license LICENSE NOTICE +%doc %ovs_dir/AUTHORS.rst %ovs_dir/CONTRIBUTING.rst %ovs_dir/NEWS %ovs_dir/README.rst +%license %ovs_dir/LICENSE %ovs_dir/NOTICE %files doc %exclude %{_docdir}/%{name}/AUTHORS.rst @@ -603,12 +1182,12 @@ fi %exclude %{_docdir}/%{name}/README.rst %{_docdir}/%{name}/ -%files -n %{lname} -%{_libdir}/libofproto-2*.so.* -%{_libdir}/libopenvswitch-2*.so.* -%{_libdir}/libovsdb-2*.so.* -%{_libdir}/libsflow-2*.so.* -%{_libdir}/libvtep-2*.so.* +%files -n %{ovs_lname} +%{_libdir}/libofproto-3*.so.* +%{_libdir}/libopenvswitch-3*.so.* +%{_libdir}/libovsdb-3*.so.* +%{_libdir}/libsflow-3*.so.* +%{_libdir}/libvtep-3*.so.* %files pki %{_mandir}/man8/ovs-pki.8%{?ext_man} @@ -626,6 +1205,10 @@ fi %{_sbindir}/rcopenvswitch-ipsec %{_unitdir}/openvswitch-ipsec.service +%files -n python3-ovs +%{python3_sitearch}/ovs/ +%{python3_sitearch}/ovs-*.egg-info + %files test %{_bindir}/ovs-l3ping %{_bindir}/ovs-pcap @@ -659,9 +1242,98 @@ fi %{_datadir}/openvswitch/ovsdb/ovsdb-doc %{_datadir}/openvswitch/ovsdb/ovsdb-dot -%files %{python_files ovs} -%license LICENSE NOTICE -%{python_sitearch}/ovs -%{python_sitearch}/ovs-%{version}* +%files -n ovn +%defattr(-,openvswitch,openvswitch) +%dir %{_localstatedir}/log/ovn +%defattr(-,root,root) +%if 0%{?suse_version} +%{_fillupdir}/sysconfig.ovn +%else +%config(noreplace) %{_sysconfdir}/sysconfig/ovn +%endif +%{_bindir}/ovn-nbctl +%{_bindir}/ovn-sbctl +%{_bindir}/ovn-trace +%{_bindir}/ovn-detrace +%{_bindir}/ovn_detrace.py +%{_bindir}/ovn-appctl +%{_bindir}/ovn-ic-nbctl +%{_bindir}/ovn-ic-sbctl +%dir %{_datadir}/ovn +%dir %{_datadir}/ovn/scripts +%{_datadir}/ovn/scripts/ovn-ctl +%{_datadir}/ovn/scripts/ovn-lib +%{_datadir}/ovn/scripts/ovndb-servers.ocf +%{_datadir}/ovn/scripts/ovn-bugtool-nbctl-show +%{_datadir}/ovn/scripts/ovn-bugtool-sbctl-lflow-list +%{_datadir}/ovn/scripts/ovn-bugtool-sbctl-show +%{_mandir}/man5/ovn-nb.5%{?ext_man} +%{_mandir}/man5/ovn-sb.5%{?ext_man} +%{_mandir}/man8/ovn-ic-nbctl.8%{?ext_man} +%{_mandir}/man8/ovn-ic-sbctl.8%{?ext_man} +%{_mandir}/man8/ovn-ic.8%{?ext_man} +%{_mandir}/man5/ovn-ic-nb.5%{?ext_man} +%{_mandir}/man5/ovn-ic-sb.5%{?ext_man} +%{_mandir}/man1/ovn-detrace.1%{?ext_man} +%{_mandir}/man8/ovn-appctl.8%{?ext_man} +%{_mandir}/man7/ovn-architecture.7%{?ext_man} +%{_mandir}/man8/ovn-ctl.8%{?ext_man} +%{_mandir}/man8/ovn-nbctl.8%{?ext_man} +%{_mandir}/man8/ovn-trace.8%{?ext_man} +%{_mandir}/man8/ovn-sbctl.8%{?ext_man} +%config(noreplace) %{_sysconfdir}/logrotate.d/ovn +%doc %ovn_dir/AUTHORS.rst %ovn_dir/CONTRIBUTING.rst %ovn_dir/NEWS %ovn_dir/README.rst +%license %ovn_dir/LICENSE %ovn_dir/NOTICE + +%files -n ovn-docker +%{_bindir}/ovn-docker-overlay-driver +%{_bindir}/ovn-docker-underlay-driver + +%files -n ovn-central +# Can't use libexecdir because it differs between +# RedHat and SUSE and firewalld expects things in /usr/lib +%dir %{_prefix}/lib/firewalld +%dir %{_prefix}/lib/firewalld/services +%{_bindir}/ovn-northd +%{_bindir}/ovn-ic +%{_mandir}/man8/ovn-northd.8%{?ext_man} +%{_datadir}/ovn/ovn-nb.ovsschema +%{_datadir}/ovn/ovn-sb.ovsschema +%{_datadir}/ovn/ovn-ic-nb.ovsschema +%{_datadir}/ovn/ovn-ic-sb.ovsschema +%{_unitdir}/ovn-northd.service +%{_sbindir}/rcovn-northd +%{_prefix}/lib/firewalld/services/ovn-central-firewall-service.xml + +%files -n ovn-host +# Can't use libexecdir because it differs between +# RedHat and SUSE and firewalld expects things in /usr/lib +%dir %{_prefix}/lib/firewalld +%dir %{_prefix}/lib/firewalld/services +%{_bindir}/ovn-controller +%{_mandir}/man8/ovn-controller.8%{?ext_man} +%{_unitdir}/ovn-controller.service +%{_sbindir}/rcovn-controller +%{_prefix}/lib/firewalld/services/ovn-host-firewall-service.xml + +%files -n ovn-vtep +%{_bindir}/ovn-controller-vtep +%{_mandir}/man8/ovn-controller-vtep.8%{?ext_man} +%{_unitdir}/ovn-controller-vtep.service +%{_sbindir}/rcovn-controller-vtep + +%files -n ovn-doc +%exclude %{_docdir}/ovn/AUTHORS.rst +%exclude %{_docdir}/ovn/CONTRIBUTING.rst +%exclude %{_docdir}/ovn/NEWS +%exclude %{_docdir}/ovn/README.rst +%{_docdir}/ovn/ + +%files -n %{ovn_lname} +%{_libdir}/libovn-*.so.* + +%files -n ovn-devel +%{_libdir}/libovn.so +%{_includedir}/ovn/ %changelog diff --git a/ovn-23.03.0.tar.gz b/ovn-23.03.0.tar.gz new file mode 100644 index 0000000..b10d294 --- /dev/null +++ b/ovn-23.03.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c351ef0b1b0a19594c2d9b3cd541da1c6aab6606b371504ba46da75b3a09e30 +size 1955554