openvswitch/0002-build-Seperated-common-used-headers.patch
Dirk Mueller 31714c7a75 - update to 2.17.2:
- Bug fixes
  - DPDK:
    * OVS validated with DPDK 21.11.1.  It is recommended to use this version
      until further releases.
  - Bug fixes
  - libopenvswitch API change:
    * To fix the Undefined Behavior issue causing the compiler to incorrectly
      optimize important parts of code, container iteration macros (e.g.,
      LIST_FOR_EACH) have been re-implemented in a UB-safe way.
    * Backwards compatibility has mostly been preserved, however the
     user-provided pointer is now set to NULL after the loop (unless it
      exited via "break;")
    * Users of libopenvswitch will need to double-check the use of such loop
       macros before compiling with a new version.
    * Since the change is limited to the definitions within the headers, the
      ABI is not affected.
- refresh 0001-openvswitch-merge-compiler.h-files-into-one-file.patch
  0002-build-Seperated-common-used-headers.patch

OBS-URL: https://build.opensuse.org/package/show/network/openvswitch?expand=0&rev=229
2022-08-03 11:12:42 +00:00

45799 lines
1.6 MiB
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 8e62dcacc834a2318cb69533f4f83d32bc950fd4 Mon Sep 17 00:00:00 2001
From: Ferdinand Thiessen <rpm@fthiessen.de>
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 <linux/openvswitch.h> -- 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 <i
echo "#ifndef ODP_NETLINK_MACROS_H"
echo "#define ODP_NETLINK_MACROS_H"
echo
+echo "#ifdef __cplusplus"
+echo 'extern "C" {'
+echo "#endif"
echo
generate_fields_macros "ovs_key_ethernet"
@@ -57,4 +60,7 @@ generate_fields_macros "ovs_key_nd"
generate_fields_macros "ovs_key_nd_extensions"
echo
+echo "#ifdef __cplusplus"
+echo '} // extern "C"'
+echo "#endif"
echo "#endif"
Index: openvswitch-2.17.2/datapath/conntrack.c
===================================================================
--- openvswitch-2.17.2.orig/datapath/conntrack.c
+++ openvswitch-2.17.2/datapath/conntrack.c
@@ -62,7 +62,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/conntrack.h
===================================================================
--- openvswitch-2.17.2.orig/datapath/conntrack.h
+++ openvswitch-2.17.2/datapath/conntrack.h
@@ -15,7 +15,7 @@
#define OVS_CONNTRACK_H 1
#include <linux/version.h>
-#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 <net/ip_tunnels.h>
#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 <net/inet_ecn.h>
#include <net/ip_tunnels.h>
-#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 <linux/uaccess.h>
#include <linux/netdevice.h>
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 <net/inet_ecn.h>
#include <net/ip_tunnels.h>
-#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 <linux/genetlink.h>
#include <linux/skbuff.h>
-#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 <limits.h>
-#include <stdlib.h>
-#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 <limits.h>
+#include <stdlib.h>
+#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 <stdbool.h>
-#include <stdint.h>
-#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 <stdbool.h>
+#include <stdint.h>
+#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 <stdint.h>
-#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 <stdint.h>
+#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 <stddef.h>
-#include <stdint.h>
-
-#ifdef DPDK_NETDEV
-#include <rte_config.h>
-#include <rte_mbuf.h>
-#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 <stddef.h>
+#include <stdint.h>
+
+#ifdef DPDK_NETDEV
+#include <rte_config.h>
+#include <rte_mbuf.h>
+#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 <sys/types.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#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 <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/icmp6.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#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 <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#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 <smmintrin.h>
-
-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 <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#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 <smmintrin.h>
+
+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 <stdbool.h>
-#include <stdlib.h>
-#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 <stdbool.h>
+#include <stdlib.h>
+#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 <stdbool.h>
-#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 <stdbool.h>
+#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 <time.h>
-#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 <time.h>
+#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 <stdint.h>
-#include <sys/socket.h>
-#include "util.h"
-
-#ifdef HAVE_NETLINK
-#include <linux/netlink.h>
-#include <linux/genetlink.h>
-
-#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 <stdint.h>
+#include <sys/socket.h>
+#include "internal/util.h"
+
+#ifdef HAVE_NETLINK
+#include <linux/netlink.h>
+#include <linux/genetlink.h>
+
+#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 <sys/types.h>
-#include <netinet/in.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#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 <sys/types.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#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 <stdint.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#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 <stdint.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#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 <config.h>
-
-#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 <config.h>
+
+#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 <inttypes.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#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 <inttypes.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#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 <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#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 <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#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 <stdbool.h>
-#include <stddef.h>
-#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 <stdbool.h>
+#include <stddef.h>
+#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 <stdint.h>
-#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 <stdint.h>
+#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 <sys/types.h>
-#include <netinet/in.h>
-#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 <sys/types.h>
+#include <netinet/in.h>
+#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 <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-#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 <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+#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 <stdbool.h>
-
-#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 <stdbool.h>
+
+#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 <time.h>
-#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 <time.h>
+#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 <stdint.h>
-
-#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 <stdint.h>
+
+#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 <stdint.h>
-#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<N>_t and ovs_be<N>, 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<N> 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 <stdint.h>
+#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<N>_t and ovs_be<N>, 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<N> 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 <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "openvswitch/compiler.h"
+#include "openvswitch/util.h"
+#if defined(__aarch64__) && __GNUC__ >= 6
+#include <arm_neon.h>
+#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<const ::Bad_arg_to_ARRAY_SIZE *>(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 <typename T>
+ 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 <limits.h>
-#include <pthread.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#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 <stdatomic.h>"
- #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 <limits.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#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 <stdatomic.h>"
+ #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 <limits.h>
-#include <stdbool.h>
-
-#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 <limits.h>
+#include <stdbool.h>
+
+#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 <pthread.h>
-#include <stddef.h>
-#include <sys/types.h>
-#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, "<unlocked>" }
-#else
-#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, "<unlocked>" }
-#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 <threads.h> 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 <threads.h>
-#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 <pthread.h>
+#include <stddef.h>
+#include <sys/types.h>
+#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, "<unlocked>" }
+#else
+#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, "<unlocked>" }
+#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 <threads.h> 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 <threads.h>
+#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 <stdbool.h>
-#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 <monitor-requests> to use for the specified <schema>. 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 <table-updates> or <table-updates2> 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 <table-updates> if 'version' if 1, otherwise a
- * <table-updates2>. 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 <table-updates> or <table-updates2> 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 /* <table-updates2> diff application. */
-};
-
-/* Partially parsed <row-update> or <row-update2>. */
-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 <table-update> or <table-update2>. */
-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 <stdbool.h>
+#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 <monitor-requests> to use for the specified <schema>. 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 <table-updates> or <table-updates2> 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 <table-updates> if 'version' if 1, otherwise a
+ * <table-updates2>. 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 <table-updates> or <table-updates2> 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 /* <table-updates2> diff application. */
+};
+
+/* Partially parsed <row-update> or <row-update2>. */
+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 <table-update> or <table-update2>. */
+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 <stdlib.h>
-#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 <stdlib.h>
+#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; /* <db-name> 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; /* <db-name> 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 <stdbool.h>
-#include <stdint.h>
-#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 <stdbool.h>
+#include <stdint.h>
+#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 <stdbool.h>
-#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 <stdbool.h>
+#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 <float.h>
-#include <stdbool.h>
-#include <stdint.h>
-#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 <float.h>
+#include <stdbool.h>
+#include <stdint.h>
+#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 <inttypes.h>
#include <netinet/in.h>
-#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 <unistd.h>
#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 <stdlib.h>
#include <unistd.h>
-#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 <netinet/ip.h>
#include <sys/socket.h>
-#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 <stdbool.h>
#include <inttypes.h>
-#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 <config.h>
-#include "bundle.h"
+#include "internal/bundle.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
-#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 <errno.h>
#include <string.h>
#include <unistd.h>
-#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 <config.h>
#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 <stdbool.h>
#include <stdint.h>
-#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 <stdlib.h>
#include <string.h>
-#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 <config.h>
-#include "classifier.h"
+#include "internal/classifier.h"
#include "classifier-private.h"
#include <errno.h>
#include <sys/types.h>
#include <netinet/in.h>
-#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 <config.h>
-#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 <config.h>
-#include "colors.h"
+#include "internal/colors.h"
#include <stdlib.h>
#include <string.h>
-#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 <config.h>
-#include "command-line.h"
+#include "internal/command-line.h"
#include <getopt.h>
#include <limits.h>
#include <stdlib.h>
-#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 <config.h>
#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 <netinet/in.h>
#include <netinet/ip6.h>
-#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 <netinet/icmp6.h>
#include <string.h>
-#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 <stdbool.h>
-#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 <config.h>
-#include "coverage.h"
+#include "internal/coverage.h"
#include <inttypes.h>
#include <stdlib.h>
#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 <config.h>
-#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 <config.h>
-#include "csum.h"
-#include "unaligned.h"
+#include "internal/csum.h"
+#include "internal/unaligned.h"
#include <sys/types.h>
#include <netinet/in.h>
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 <config.h>
#include "backtrace.h"
-#include "daemon.h"
+#include "internal/daemon.h"
#include "daemon-private.h"
#include <errno.h>
#include <fcntl.h>
@@ -32,15 +32,15 @@
#if HAVE_LIBCAPNG
#include <cap-ng.h>
#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 <config.h>
-#include "daemon.h"
+#include "internal/daemon.h"
#include "daemon-private.h"
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <unistd.h>
-#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 <config.h>
-#include "daemon.h"
+#include "internal/daemon.h"
#include "daemon-private.h"
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
-#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 <getopt.h>
#include <unistd.h>
-#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 <config.h>
-#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 <config.h>
-#include "dirs.h"
+#include "internal/dirs.h"
#include <stdlib.h>
-#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 <string.h>
#include <sys/stat.h>
#include <unbound.h>
-#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 <stdlib.h>
#include <string.h>
-#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 <string.h>
#include <unistd.h>
+#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 <config.h>
#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 <rte_memzone.h>
#include <rte_version.h>
-#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 <errno.h>
#include <immintrin.h>
-#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 <string.h>
#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 <stdbool.h>
#include <stdint.h>
-#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 <stdint.h>
#include <string.h>
-#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 <stdbool.h>
#include <stdint.h>
-#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 <stdint.h>
#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 <sys/stat.h>
#include <unistd.h>
-#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 <stdint.h>
#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 <errno.h>
-#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 <sys/stat.h>
#include <unistd.h>
-#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 <stddef.h>
#include <stdint.h>
-#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 <stdlib.h>
#include <string.h>
-#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 <stdint.h>
#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 <config.h>
#include "dummy.h"
#include <string.h>
-#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 <stdlib.h>
#include <string.h>
#include <time.h>
-#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 <Wincrypt.h>
#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 <config.h>
#include "backtrace.h"
-#include "fatal-signal.h"
+#include "internal/fatal-signal.h"
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
@@ -24,13 +24,13 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#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 <config.h>
#include <sys/types.h>
-#include "flow.h"
+#include "internal/flow.h"
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
@@ -26,21 +26,21 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#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 <getopt.h>
#include <stdlib.h>
#include <string.h>
-#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 <psapi.h>
#include <sys/resource.h>
#include <time.h>
-#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 <stddef.h>
#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 <config.h>
-#include "hash.h"
+#include "internal/hash.h"
#include <string.h>
-#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 <config.h>
#include "heap.h"
#include <stdlib.h>
-#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 <config.h>
-#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 <stdint.h>
#include <string.h>
-#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 <config.h>
-#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 <config.h>
-#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 <config.h>
#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 <config.h>
#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 <netinet/icmp6.h>
#include <string.h>
-#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 <config.h>
#include "jhash.h"
#include <string.h>
-#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 <stddef.h>
#include <stdint.h>
#include <string.h>
-#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 <string.h>
#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 <config.h>
-#include "jsonrpc.h"
+#include "internal/jsonrpc.h"
#include <errno.h>
#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 <stdbool.h>
#include <stdint.h>
-#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 <config.h>
-#include "latch.h"
+#include "internal/latch.h"
#include <errno.h>
#include <poll.h>
#include <unistd.h>
#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 <config.h>
-#include "latch.h"
+#include "internal/latch.h"
#include <errno.h>
#include <poll.h>
#include <unistd.h>
#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 <stdlib.h>
#include <time.h>
-#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 <sys/socket.h>
#include <sys/types.h>
#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 <stdlib.h>
#include <unistd.h>
#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 <sys/socket.h>
#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 <stdlib.h>
#include <stddef.h>
#include <string.h>
-#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 <sys/stat.h>
#include <unistd.h>
-#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 <inttypes.h>
#include <stdlib.h>
-#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 <config.h>
#include "openvswitch/match.h"
#include <stdlib.h>
-#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 <config.h>
-#include "mcast-snooping.h"
+#include "internal/mcast-snooping.h"
#include <inttypes.h>
#include <stdlib.h>
-#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 <config.h>
-#include "memory.h"
+#include "internal/memory.h"
#include <stdbool.h>
#include <sys/time.h>
#include <sys/resource.h>
#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 <netinet/icmp6.h>
#include <netinet/ip6.h>
-#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 <config.h>
-#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 <openvswitch/thread.h>
#include <openvswitch/util.h>
-#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 <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
-#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 <config.h>
#include "openvswitch/namemap.h"
#include <ctype.h>
-#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 <config.h>
-#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 <stdbool.h>
#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 <errno.h>
@@ -35,19 +35,19 @@
#include <sys/types.h>
#include <unistd.h>
-#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 <config.h>
-#include "netdev-dpdk.h"
+#include "internal/netdev-dpdk.h"
#include <errno.h>
#include <signal.h>
@@ -39,13 +39,13 @@
#include <rte_version.h>
#include <rte_vhost.h>
-#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 <errno.h>
#include <unistd.h>
-#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 <stdint.h>
#include <stdbool.h>
-#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 <string.h>
#include <unistd.h>
-#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 <stdlib.h>
#include <sys/time.h>
-#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 <stdbool.h>
#include <stddef.h>
#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 <rte_flow.h>
#include <rte_gre.h>
-#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 <linux/if_ether.h>
#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 <string.h>
#include <unistd.h>
-#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 <stdbool.h>
#include <stddef.h>
#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 <netinet/ip6.h>
#include <sys/ioctl.h>
-#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 <net/if.h>
-#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 <config.h>
-#include "netdev.h"
+#include "internal/netdev.h"
#include <errno.h>
#include <inttypes.h>
@@ -31,31 +31,31 @@
#include <sys/ioctl.h>
#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 <stdint.h>
#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 <linux/netfilter/nf_conntrack_ftp.h>
#include <linux/netfilter/nf_conntrack_sctp.h>
-#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 <linux/netfilter/nfnetlink_cttimeout.h>
-#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 <poll.h>
#include <stdlib.h>
-#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 <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
-#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 <stddef.h>
#include <stdint.h>
#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 <config.h>
-#include "netlink.h"
+#include "internal/netlink.h"
#include <errno.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
-#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 <config.h>
-#include "nx-match.h"
+#include "internal/nx-match.h"
#include <netinet/icmp6.h>
-#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 <config.h>
#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 <stdlib.h>
#include <string.h>
-#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 <stdlib.h>
#include <string.h>
-#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 <stddef.h>
#include <stdint.h>
#include <string.h>
-#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 <sys/types.h>
#include <netinet/in.h>
-#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 <config.h>
#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 <config.h>
#include <errno.h>
-#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 <config.h>
#include "openvswitch/ofp-flow.h"
#include <errno.h>
-#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 <config.h>
#include "openvswitch/ofp-group.h"
#include <errno.h>
-#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 <config.h>
#include "openvswitch/ofp-ipfix.h"
#include <stdlib.h>
-#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 <config.h>
#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 <config.h>
#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 <config.h>
#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 <config.h>
-#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 <config.h>
#include "openvswitch/ofp-packet.h"
#include <string.h>
-#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 <config.h>
#include "openvswitch/ofp-parse.h"
#include <errno.h>
-#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 <config.h>
#include "openvswitch/ofp-port.h"
#include <ctype.h>
-#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 <stdlib.h>
#include <ctype.h>
-#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 <config.h>
-#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 <config.h>
#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 <config.h>
#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 <config.h>
#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 <netinet/in.h>
#include <netinet/icmp6.h>
#include <stdlib.h>
-#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 <openflow/openflow-common.h>
-#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 <stdlib.h>
#include <string.h>
#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 <stdbool.h>
#include <stdlib.h>
#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 <stdint.h>
-#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 <config.h>
-#include "ovs-numa.h"
+#include "openvswitch/ovs-numa.h"
#include <ctype.h>
#include <errno.h>
@@ -27,12 +27,12 @@
#include <unistd.h>
#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 <config.h>
#include <errno.h>
-#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 <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
-#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 <string.h>
#include <unistd.h>
-#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 <sys/types.h>
#include <netinet/in.h>
-#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 <config.h>
-#include "ovs-thread.h"
+#include "openvswitch/ovs-thread.h"
#include <errno.h>
#include <poll.h>
#ifndef _WIN32
@@ -24,14 +24,14 @@
#include <stdlib.h>
#include <unistd.h>
#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 <config.h>
#include <string.h>
-#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 <config.h>
-#include "ovsdb-cs.h"
+#include "openvswitch/ovsdb-cs.h"
#include <errno.h>
-#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 <config.h>
-#include "ovsdb-data.h"
+#include "openvswitch/ovsdb-data.h"
#include <ctype.h>
#include <float.h>
@@ -23,16 +23,16 @@
#include <limits.h>
#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 <config.h>
-#include "ovsdb-error.h"
+#include "openvswitch/ovsdb-error.h"
#include <inttypes.h>
#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 <config.h>
-#include "ovsdb-idl.h"
+#include "openvswitch/ovsdb-idl.h"
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
-#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 <config.h>
-#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 <config.h>
-#include "ovsdb-parser.h"
+#include "openvswitch/ovsdb-parser.h"
#include <ctype.h>
#include <stdarg.h>
-#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 <stdbool.h>
#include <stddef.h>
#include <string.h>
-#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 <config.h>
-#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 <config.h>
-#include "ovsdb-types.h"
+#include "openvswitch/ovsdb-types.h"
#include <float.h>
#include <limits.h>
#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 <config.h>
#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 <config.h>
-#include "packets.h"
+#include "internal/packets.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -24,16 +24,16 @@
#include <netinet/icmp6.h>
#include <stdlib.h>
#include <netdb.h>
-#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 <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-#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 <poll.h>
#include <stdlib.h>
#include <string.h>
-#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 <config.h>
-#include "process.h"
+#include "internal/process.h"
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
@@ -25,16 +25,16 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
-#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 <config.h>
-#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 <config.h>
-#include "random.h"
+#include "internal/random.h"
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#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 <limits.h>
#include <stdlib.h>
#include <string.h>
-#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 <stdlib.h>
#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 <unistd.h>
#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 <linux/rtnetlink.h>
#include <net/if.h>
-#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 <stdint.h>
#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 <arpa/inet.h>
#include <inttypes.h>
#include <stdlib.h>
-#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 <arpa/inet.h>
#include <inttypes.h>
#include <stdlib.h>
-#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 <stdint.h>
#include <stdbool.h>
#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 <net/route.h>
#include <poll.h>
-#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 <linux/rtnetlink.h>
#include <net/if.h>
-#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 <config.h>
-#include "seq.h"
+#include "internal/seq.h"
#include <stdbool.h>
-#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 <ctype.h>
#include <string.h>
#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 <config.h>
#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 <stdlib.h>
#include <unistd.h>
#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 <config.h>
-#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 <stdlib.h>
#include <string.h>
-#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 <config.h>
-#include "smap.h"
+#include "internal/smap.h"
#include <strings.h>
-#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 <config.h>
-#include "socket-util.h"
+#include "internal/socket-util.h"
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
@@ -25,9 +25,9 @@
#include <sys/un.h>
#include <sys/wait.h>
#include <unistd.h>
-#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 <config.h>
-#include "socket-util.h"
+#include "internal/socket-util.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -36,16 +36,16 @@
#include <sys/un.h>
#include <unistd.h>
#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 <linux/if_packet.h>
#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 <config.h>
-#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 <config.h>
-#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 <config.h>
-#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 <unistd.h>
-#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 <arpa/inet.h>
#include <inttypes.h>
#include <stdlib.h>
-#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 <stdbool.h>
#include <stdint.h>
#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 <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
-#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 <config.h>
-#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 <sys/types.h>
#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 <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
-#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 <config.h>
-#include "stream-ssl.h"
-#include "dhparams.h"
+#include "internal/stream-ssl.h"
+#include "internal/dhparams.h"
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
@@ -32,19 +32,19 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
-#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 <config.h>
-#include "stream.h"
+#include "internal/stream.h"
#include <errno.h>
#include <inttypes.h>
#include <sys/types.h>
@@ -26,9 +26,9 @@
#include <sys/socket.h>
#include <unistd.h>
#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 <config.h>
-#include "stream.h"
+#include "internal/stream.h"
#include <errno.h>
#include <inttypes.h>
#include <netdb.h>
@@ -26,12 +26,12 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#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 <string.h>
#include <unistd.h>
#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 <poll.h>
#include <stdlib.h>
#include <string.h>
-#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 <ctype.h>
#include <string.h>
-#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 <config.h>
-#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 <config.h>
-#include "svec.h"
+#include "internal/svec.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#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 <config.h>
-#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 <net/if.h>
#include <unistd.h>
-#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 <config.h>
-#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 <config.h>
-#include "timeval.h"
+#include "internal/timeval.h"
#include <errno.h>
#include <poll.h>
#include <pthread.h>
@@ -25,18 +25,18 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
-#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 <netinet/icmp6.h>
#include <stdlib.h>
-#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 <net/if.h>
#include <sys/socket.h>
-#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 <stdint.h>
#include <string.h>
-#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 <net/if.h>
#include <sys/socket.h>
-#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 <errno.h>
#include <stdbool.h>
-#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 <inttypes.h>
#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 <config.h>
-#include "unixctl.h"
+#include "internal/unixctl.h"
#include <errno.h>
#include <unistd.h>
-#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 <config.h>
-#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 <config.h>
-#include "util.h"
+#include "internal/util.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
@@ -27,13 +27,13 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
-#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 <pthread_np.h>
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 <stdlib.h>
#include <string.h>
#include "openvswitch/compiler.h"
-#include "util.h"
#include "openvswitch/util.h"
#if defined(__aarch64__) && __GNUC__ >= 6
#include <arm_neon.h>
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 <config.h>
-#include "uuid.h"
+#include "internal/uuid.h"
#include <ctype.h>
#include <errno.h>
@@ -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 <string.h>
#include <sys/types.h>
#include <unistd.h>
-#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 <poll.h>
#include <stdlib.h>
#include <string.h>
-#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 <stdbool.h>
#include <stdint.h>
-#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 <time.h>
#include <unistd.h>
#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 <stdio.h>
#include <tchar.h>
#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 <math.h>
#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 <stdbool.h>
#include <stdint.h>
#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 <config.h>
#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 <sys/socket.h>
#include <unistd.h>
-#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 <config.h>
#include <inttypes.h>
#include <stdlib.h>
-#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 <net/if.h>
#include <string.h>
#include <stdlib.h>
-#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 <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
-#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 <errno.h>
#include <stdlib.h>
#include <unistd.h>
-#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 <stdint.h>
-#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 <config.h>
#include "ofproto-dpif-ipfix.h"
#include <sys/time.h>
-#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 <errno.h>
-#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 <stdint.h>
-#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 <stdint.h>
#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 <stddef.h>
#include <stdint.h>
-#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 <stdint.h>
-#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 <inttypes.h>
#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 <sys/socket.h>
#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 <netinet/in.h>
#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 <sys/socket.h>
#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 <stdlib.h>
#include <unistd.h>
-#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 <stddef.h>
#include <stdint.h>
#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 <arpa/inet.h>
#include <stdint.h>
#include <stdlib.h>
-#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 <stdint.h>
-#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 <config.h>
#include <errno.h>
-#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 <stdbool.h>
#include <stdint.h>
-#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 <stdbool.h>
#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 <string.h>
#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 <stddef.h>
#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 <fcntl.h>
#include <unistd.h>
-#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 <errno.h>
-#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 <errno.h>
-#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 <limits.h>
#include "column.h"
-#include "ovsdb-error.h"
+#include "openvswitch/ovsdb-error.h"
#include "openvswitch/json.h"
#include "row.h"
#include <string.h>
#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 <stddef.h>
#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 <string.h>
#include <unistd.h>
-#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 <stddef.h>
#include <stdint.h>
#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 <config.h>
#include %(header)s
#include <limits.h>
-#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 <unistd.h>
#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 <string.h>
#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 <config.h>
#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 <stdint.h>
#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 <stdlib.h>
#include <string.h>
#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 <errno.h>
#include <unistd.h>
-#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 <stdbool.h>
#include <stdint.h>
#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 <string.h>
#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 <config.h>
-#include "classifier.h"
+#include "internal/classifier.h"
#include <assert.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"
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 <config.h>
#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 <assert.h>
#include <string.h>
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 <config.h>
-#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 <stdio.h>
#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 <config.h>
#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 <inttypes.h>
#include <limits.h>
#include <stdlib.h>
-#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 <ctype.h>
#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 <config.h>
#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 <config.h>
-#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 <config.h>
#undef NDEBUG
-#include "bitmap.h"
+#include "internal/bitmap.h"
#include <assert.h>
-#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 <math.h>
#include <stdlib.h>
-#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 <config.h>
#undef NDEBUG
-#include "byte-order.h"
+#include "internal/byte-order.h"
#include <assert.h>
#include <inttypes.h>
#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 <assert.h>
#include <getopt.h>
#include <string.h>
-#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 <config.h>
#undef NDEBUG
-#include "classifier.h"
+#include "internal/classifier.h"
#include <assert.h>
#include <errno.h>
#include <limits.h>
-#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 <config.h>
#undef NDEBUG
-#include "cmap.h"
+#include "internal/cmap.h"
#include <assert.h>
#include <getopt.h>
#include <string.h>
-#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 <config.h>
#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 <config.h>
#undef NDEBUG
-#include "csum.h"
+#include "internal/csum.h"
#include <assert.h>
#include <inttypes.h>
#include <sys/types.h>
@@ -25,12 +25,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#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 <config.h>
#undef NDEBUG
-#include "flow.h"
+#include "internal/flow.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#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 <config.h>
#undef NDEBUG
-#include "hash.h"
+#include "internal/hash.h"
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
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 <inttypes.h>
#include <limits.h>
#include <stdlib.h>
-#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 <config.h>
#undef NDEBUG
-#include "hindex.h"
+#include "internal/hindex.h"
#include <assert.h>
#include <string.h>
-#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 <assert.h>
#include <string.h>
-#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 <config.h>
-#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 <getopt.h>
#include <stdio.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"
/* --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 <config.h>
#undef NDEBUG
-#include "jsonrpc.h"
+#include "internal/jsonrpc.h"
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
-#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 <sys/wait.h>
#include <unistd.h>
#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 <config.h>
-#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 <math.h>
#include <stdio.h>
#include <stdlib.h>
-#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 <signal.h>
#include <stdlib.h>
#include <unistd.h>
-#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 <string.h>
-#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 <stdio.h>
#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 <stdio.h>
#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 <stdio.h>
#include <stdlib.h>
-#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 <config.h>
#undef NDEBUG
-#include "packets.h"
+#include "internal/packets.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
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 <config.h>
#undef NDEBUG
-#include "random.h"
+#include "internal/random.h"
#include <stdio.h>
#include <string.h>
#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 <config.h>
#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
+#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 <stdlib.h>
#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 <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
-#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 <stdlib.h>
#include <string.h>
#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 <stdio.h>
#include <string.h>
#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 <config.h>
#undef NDEBUG
-#include "stopwatch.h"
+#include "internal/stopwatch.h"
#include <assert.h>
#include <math.h>
#include <stdio.h>
#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 <inttypes.h>
#include <stdarg.h>
#include <stdlib.h>
-#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 <config.h>
-#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 <config.h>
#undef NDEBUG
-#include "socket-util.h"
+#include "internal/socket-util.h"
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#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 <getopt.h>
-#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 <config.h>
#undef NDEBUG
-#include "util.h"
+#include "internal/util.h"
#include <assert.h>
#include <getopt.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
-#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 <config.h>
#undef NDEBUG
-#include "util.h"
-#include "uuid.h"
+#include "internal/util.h"
+#include "internal/uuid.h"
#include <stdio.h>
#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 <signal.h>
#include <stdlib.h>
#include <unistd.h>
-#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 <sys/uio.h>
#include <stddef.h>
#include <linux/rtnetlink.h>
-#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 <string.h>
#include <stdlib.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 "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 <sys/time.h>
#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 <sys/stat.h>
#include <sys/time.h>
-#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 <stdio.h>
#include <string.h>
+#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 <string.h>
#include <unistd.h>
-#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 <unistd.h>
-#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 <string.h>
#include <unistd.h>
#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 <string.h>
#include <unistd.h>
-#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 <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#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 <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <inttypes.h>
+#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 <stdbool.h>
+
+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 <stddef.h>
+#include <stdint.h>
+#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 <limits.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+/* 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 <inttypes.h>
+#include <openssl/dh.h>
+
+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 <signal.h>
+#endif
+#include <stdbool.h>
+
+/* 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 <arm_acle.h>
+
+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 <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+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 <stdbool.h>
+#include <stddef.h>
+#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 <stdbool.h>
+
+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 <stdint.h>
+#include <stdbool.h>
+
+/* 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 <config.h>
+
+#include "openvswitch/compiler.h"
+
+struct dp_packet;
+struct netdev;
+
+#ifdef DPDK_NETDEV
+
+#include <rte_flow.h>
+
+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 <atomic> */
+#ifndef IN_OVS_ATOMIC_H
+#error "This header should only be included indirectly via ovs-atomic.h."
+#endif
+
+#include <atomic>
+
+#define ATOMIC(TYPE) std::atomic<TYPE>
+
+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 <stdatomic.h> */
+#ifndef IN_OVS_ATOMIC_H
+#error "This header should only be included indirectly via ovs-atomic.h."
+#endif
+
+#include <stdatomic.h>
+
+#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 <stdbool.h>
+#include <sys/types.h>
+
+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 <stddef.h>
+#include <stdint.h>
+
+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 <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+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 <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include "openvswitch/types.h"
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+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 <netinet/ip.h> 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 <stddef.h>
+
+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 <stdbool.h>
+
+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 <stdbool.h>
+
+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 <stdbool.h>
+#include <stddef.h>
+
+#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 <stdbool.h>
+#include <stddef.h>
+#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 <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#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 <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <inttypes.h>
-#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 <stdbool.h>
-
-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 <stddef.h>
-#include <stdint.h>
-#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 <limits.h>
-#include <stdbool.h>
-#include <sys/types.h>
-
-/* 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 <inttypes.h>
-#include <openssl/dh.h>
-
-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 <signal.h>
-#endif
-#include <stdbool.h>
-
-/* 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 <arm_acle.h>
-
-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 <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-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 <stdbool.h>
-#include <stddef.h>
-#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 <stdbool.h>
-
-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 <stdint.h>
-#include <stdbool.h>
-
-/* 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 <config.h>
-
-#include "openvswitch/compiler.h"
-
-struct dp_packet;
-struct netdev;
-
-#ifdef DPDK_NETDEV
-
-#include <rte_flow.h>
-
-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 <atomic> */
-#ifndef IN_OVS_ATOMIC_H
-#error "This header should only be included indirectly via ovs-atomic.h."
-#endif
-
-#include <atomic>
-
-#define ATOMIC(TYPE) std::atomic<TYPE>
-
-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 <stdatomic.h> */
-#ifndef IN_OVS_ATOMIC_H
-#error "This header should only be included indirectly via ovs-atomic.h."
-#endif
-
-#include <stdatomic.h>
-
-#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 <stdbool.h>
-#include <sys/types.h>
-
-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 <stddef.h>
-#include <stdint.h>
-
-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 <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-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 <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <stdbool.h>
-#include "openvswitch/types.h"
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-
-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 <netinet/ip.h> 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 <stddef.h>
-
-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 <stdbool.h>
-
-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 <stdbool.h>
-
-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 <stdbool.h>
-#include <stddef.h>
-
-#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 <stdbool.h>
-#include <stddef.h>
-#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 */