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