diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5651078
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+SOURCES/*.tar.gz
+SRPMS
diff --git a/.ovn.metadata b/.ovn.metadata
new file mode 100644
index 0000000..5e00597
--- /dev/null
+++ b/.ovn.metadata
@@ -0,0 +1,5 @@
+002450621b33c5690060345b0aac25bc2426d675 SOURCES/docutils-0.12.tar.gz
+5953db6f7d13eeaa4335f558659865c07abd3d95 SOURCES/openvswitch-ba159ee.tar.gz
+54b0b39b351e7b650d4de61ac8029b4b1186896c SOURCES/ovn-22.03.0.tar.gz
+d34f96421a86004aa5d26ecf975edefd09f948b1 SOURCES/Pygments-1.4.tar.gz
+6beb30f18ffac3de7689b7fd63e9a8a7d9c8df3a SOURCES/Sphinx-1.1.3.tar.gz
diff --git a/SOURCES/arm64-armv8a-linuxapp-gcc-config b/SOURCES/arm64-armv8a-linuxapp-gcc-config
new file mode 100644
index 0000000..5813d7a
--- /dev/null
+++ b/SOURCES/arm64-armv8a-linuxapp-gcc-config
@@ -0,0 +1,540 @@
+# -*- cfg-sha: 9fc8b53ccd53cc8b64391f6252e1dba558ae660a73a72f10dcadff2ca5462243
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2015 Cavium, Inc
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Cavium, Inc
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2016 Intel Corporation
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2017 Intel Corporation
+# RTE_EXEC_ENV values are the directories in mk/exec-env/
+CONFIG_RTE_EXEC_ENV="linuxapp"
+# RTE_ARCH values are architecture we compile for. directories in mk/arch/
+CONFIG_RTE_ARCH="arm64"
+# machine can define specific variables or action for a specific board
+# RTE_MACHINE values are architecture we compile for. directories in mk/machine/
+CONFIG_RTE_MACHINE="armv8a"
+# The compiler we use.
+# RTE_TOOLCHAIN values are architecture we compile for. directories in mk/toolchain/
+CONFIG_RTE_TOOLCHAIN="gcc"
+# Use intrinsics or assembly code for key routines
+CONFIG_RTE_FORCE_INTRINSICS=y
+# Machine forces strict alignment constraints.
+CONFIG_RTE_ARCH_STRICT_ALIGN=n
+# Compile to share library
+CONFIG_RTE_BUILD_SHARED_LIB=n
+# Use newest code breaking previous ABI
+CONFIG_RTE_NEXT_ABI=n
+# Major ABI to overwrite library specific LIBABIVER
+CONFIG_RTE_MAJOR_ABI=
+# Machine's cache line size
+CONFIG_RTE_CACHE_LINE_SIZE=128
+# Memory model
+CONFIG_RTE_USE_C11_MEM_MODEL=y
+# Compile Environment Abstraction Layer
+CONFIG_RTE_LIBRTE_EAL=y
+CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_MAX_NUMA_NODES=8
+CONFIG_RTE_MAX_HEAPS=32
+CONFIG_RTE_MAX_MEMSEG_LISTS=64
+# each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
+# or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
+CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
+CONFIG_RTE_MAX_MEM_MB_PER_LIST=32768
+# a "type" is a combination of page size and NUMA node. total number of memseg
+# lists per type will be limited to either RTE_MAX_MEMSEG_PER_TYPE pages (split
+# over multiple lists of RTE_MAX_MEMSEG_PER_LIST pages), or
+# RTE_MAX_MEM_MB_PER_TYPE megabytes of memory (split over multiple lists of
+# RTE_MAX_MEM_MB_PER_LIST), whichever is smaller
+CONFIG_RTE_MAX_MEMSEG_PER_TYPE=32768
+CONFIG_RTE_MAX_MEM_MB_PER_TYPE=131072
+# global maximum usable amount of VA, in megabytes
+CONFIG_RTE_MAX_MEM_MB=524288
+CONFIG_RTE_MAX_MEMZONE=2560
+CONFIG_RTE_MAX_TAILQ=32
+CONFIG_RTE_ENABLE_ASSERT=n
+CONFIG_RTE_LOG_DP_LEVEL=RTE_LOG_INFO
+CONFIG_RTE_LOG_HISTORY=256
+CONFIG_RTE_BACKTRACE=y
+CONFIG_RTE_LIBEAL_USE_HPET=n
+CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
+CONFIG_RTE_EAL_IGB_UIO=n
+CONFIG_RTE_EAL_VFIO=y
+CONFIG_RTE_MAX_VFIO_GROUPS=64
+CONFIG_RTE_MAX_VFIO_CONTAINERS=64
+CONFIG_RTE_MALLOC_DEBUG=n
+CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=y
+CONFIG_RTE_USE_LIBBSD=n
+# Recognize/ignore architecture we compile for. AVX/AVX512 CPU flags for performance/power testing.
+# AVX512 is marked as experimental for now, will enable it after enough
+# field test and possible optimization.
+CONFIG_RTE_ENABLE_AVX=y
+CONFIG_RTE_ENABLE_AVX512=n
+# Default driver path (or "" to disable)
+CONFIG_RTE_EAL_PMD_PATH=""
+# Compile Environment Abstraction Layer to support Vmware TSC map
+CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
+# Compile architecture we compile for. PCI library
+CONFIG_RTE_LIBRTE_PCI=y
+# Compile architecture we compile for. argument parser library
+CONFIG_RTE_LIBRTE_KVARGS=y
+# Compile generic ethernet library
+CONFIG_RTE_LIBRTE_ETHER=y
+CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
+CONFIG_RTE_MAX_ETHPORTS=32
+CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
+CONFIG_RTE_LIBRTE_IEEE1588=n
+CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
+CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
+CONFIG_RTE_ETHDEV_PROFILE_WITH_VTUNE=n
+# Turn off Tx preparation stage
+# Warning: rte_eth_tx_prepare() can be safely disabled only if using a
+# driver which do not implement any Tx preparation.
+CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
+# Common libraries, before Bus/PMDs
+CONFIG_RTE_LIBRTE_COMMON_DPAAX=n
+# Compile architecture we compile for. Intel FPGA bus
+CONFIG_RTE_LIBRTE_IFPGA_BUS=n
+# Compile PCI bus driver
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+# Compile architecture we compile for. vdev bus
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
+# Compile ARK PMD
+CONFIG_RTE_LIBRTE_ARK_PMD=n
+CONFIG_RTE_LIBRTE_ARK_PAD_TX=y
+CONFIG_RTE_LIBRTE_ARK_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_STATS=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_TRACE=n
+# Compile Aquantia Atlantic PMD driver
+CONFIG_RTE_LIBRTE_ATLANTIC_PMD=n
+# Compile AMD PMD
+CONFIG_RTE_LIBRTE_AXGBE_PMD=n
+CONFIG_RTE_LIBRTE_AXGBE_PMD_DEBUG=n
+# Compile burst-oriented Broadcom PMD driver
+CONFIG_RTE_LIBRTE_BNX2X_PMD=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
+# Compile burst-oriented Broadcom BNXT PMD driver
+CONFIG_RTE_LIBRTE_BNXT_PMD=n
+# Compile burst-oriented Chelsio Terminator (CXGBE) PMD
+CONFIG_RTE_LIBRTE_CXGBE_PMD=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_CXGBE_TPUT=y
+# NXP DPAA Bus
+CONFIG_RTE_LIBRTE_DPAA_BUS=n
+CONFIG_RTE_LIBRTE_DPAA_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA_PMD=n
+CONFIG_RTE_LIBRTE_DPAA_HWDEBUG=n
+# Compile NXP DPAA2 FSL-MC Bus
+CONFIG_RTE_LIBRTE_FSLMC_BUS=n
+# Compile Support Libraries for NXP DPAA2
+CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
+# Compile burst-oriented NXP DPAA2 PMD driver
+CONFIG_RTE_LIBRTE_DPAA2_PMD=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
+# Compile NXP ENETC PMD Driver
+CONFIG_RTE_LIBRTE_ENETC_PMD=n
+# Compile burst-oriented Amazon ENA PMD driver
+CONFIG_RTE_LIBRTE_ENA_PMD=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_ENA_COM_DEBUG=n
+# Compile burst-oriented Cisco ENIC PMD driver
+CONFIG_RTE_LIBRTE_ENIC_PMD=n
+# Compile burst-oriented IGB & EM PMD drivers
+CONFIG_RTE_LIBRTE_EM_PMD=n
+CONFIG_RTE_LIBRTE_IGB_PMD=y
+CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
+# Compile burst-oriented IXGBE PMD driver
+CONFIG_RTE_LIBRTE_IXGBE_PMD=y
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
+CONFIG_RTE_IXGBE_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_IXGBE_BYPASS=n
+# Compile burst-oriented I40E PMD driver
+CONFIG_RTE_LIBRTE_I40E_PMD=y
+CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
+CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
+# Compile burst-oriented FM10K PMD
+CONFIG_RTE_LIBRTE_FM10K_PMD=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
+CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
+# Compile burst-oriented AVF PMD driver
+CONFIG_RTE_LIBRTE_AVF_PMD=n
+CONFIG_RTE_LIBRTE_AVF_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_AVF_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_AVF_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_AVF_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_AVF_16BYTE_RX_DESC=n
+# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
+CONFIG_RTE_LIBRTE_MLX4_PMD=n
+CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS=n
+# Compile burst-oriented Mellanox ConnectX-4, ConnectX-5 & Bluefield
+# (MLX5) PMD
+CONFIG_RTE_LIBRTE_MLX5_PMD=n
+CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS=n
+# Compile burst-oriented Netronome NFP PMD driver
+CONFIG_RTE_LIBRTE_NFP_PMD=n
+CONFIG_RTE_LIBRTE_NFP_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_NFP_DEBUG_RX=n
+# QLogic 10G/25G/40G/50G/100G PMD
+CONFIG_RTE_LIBRTE_QEDE_PMD=n
+CONFIG_RTE_LIBRTE_QEDE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_QEDE_DEBUG_RX=n
+#Provides abs path/name of architecture we compile for. firmware file.
+#Empty string denotes driver will use default firmware
+CONFIG_RTE_LIBRTE_QEDE_FW=""
+# Compile burst-oriented Solarflare libefx-based PMD
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
+CONFIG_RTE_LIBRTE_SFC_EFX_DEBUG=n
+# Compile software PMD backed by SZEDATA2 device
+CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
+# Compile burst-oriented Cavium Thunderx NICVF PMD driver
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD=n
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX=n
+# Compile burst-oriented Cavium LiquidIO PMD driver
+CONFIG_RTE_LIBRTE_LIO_PMD=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_REGS=n
+# Compile burst-oriented Cavium OCTEONTX network PMD driver
+CONFIG_RTE_LIBRTE_OCTEONTX_PMD=n
+# Compile WRS accelerated virtual port (AVP) guest PMD driver
+CONFIG_RTE_LIBRTE_AVP_PMD=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_BUFFERS=n
+# Compile burst-oriented VIRTIO PMD driver
+CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
+# Compile virtio device emulation inside virtio PMD driver
+CONFIG_RTE_VIRTIO_USER=n
+# Compile burst-oriented VMXNET3 PMD driver
+CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
+# Compile software PMD backed by AF_PACKET sockets (Linux only)
+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
+# Compile link bonding PMD library
+CONFIG_RTE_LIBRTE_PMD_BOND=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
+# Compile fail-safe PMD
+CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y
+# Compile Marvell PMD driver
+CONFIG_RTE_LIBRTE_MVPP2_PMD=n
+# Compile Marvell MVNETA PMD driver
+CONFIG_RTE_LIBRTE_MVNETA_PMD=n
+# Compile support for VMBus library
+CONFIG_RTE_LIBRTE_VMBUS=n
+# Compile native PMD for Hyper-V/Azure
+CONFIG_RTE_LIBRTE_NETVSC_PMD=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_DUMP=n
+# Compile virtual device driver for NetVSC on Hyper-V/Azure
+CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD=n
+# Compile null PMD
+CONFIG_RTE_LIBRTE_PMD_NULL=n
+# Compile software PMD backed by PCAP files
+CONFIG_RTE_LIBRTE_PMD_PCAP=n
+# Compile example software rings based PMD
+CONFIG_RTE_LIBRTE_PMD_RING=y
+CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
+CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
+# Compile SOFTNIC PMD
+CONFIG_RTE_LIBRTE_PMD_SOFTNIC=n
+# Compile architecture we compile for. TAP PMD
+# It is enabled by default for Linux only.
+CONFIG_RTE_LIBRTE_PMD_TAP=y
+# Do prefetch of packet data within PMD driver receive function
+CONFIG_RTE_PMD_PACKET_PREFETCH=y
+# Compile generic wireless base band device library
+# EXPERIMENTAL: API may change without prior notice
+CONFIG_RTE_LIBRTE_BBDEV=n
+CONFIG_RTE_BBDEV_MAX_DEVS=128
+CONFIG_RTE_BBDEV_OFFLOAD_COST=n
+# Compile PMD for NULL bbdev device
+CONFIG_RTE_LIBRTE_PMD_BBDEV_NULL=y
+# Compile PMD for turbo software bbdev device
+CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW=n
+# Compile generic crypto device library
+CONFIG_RTE_LIBRTE_CRYPTODEV=n
+CONFIG_RTE_CRYPTO_MAX_DEVS=64
+# Compile PMD for ARMv8 Crypto device
+CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO=n
+CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO_DEBUG=n
+# Compile NXP CAAM JR crypto Driver
+CONFIG_RTE_LIBRTE_PMD_CAAM_JR=n
+CONFIG_RTE_LIBRTE_PMD_CAAM_JR_BE=n
+# Compile NXP DPAA2 crypto sec driver for CAAM HW
+CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=n
+# NXP DPAA caam - crypto driver
+CONFIG_RTE_LIBRTE_PMD_DPAA_SEC=n
+CONFIG_RTE_LIBRTE_DPAA_MAX_CRYPTODEV=4
+# Compile PMD for Cavium OCTEON TX crypto device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_CRYPTO=y
+# Compile PMD for QuickAssist based devices - see docs for details
+CONFIG_RTE_LIBRTE_PMD_QAT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_SYM=n
+# Max. number of QuickAssist devices, which can be detected and attached
+CONFIG_RTE_PMD_QAT_MAX_PCI_DEVICES=48
+CONFIG_RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS=16
+CONFIG_RTE_PMD_QAT_COMP_IM_BUFFER_SIZE=65536
+# Compile PMD for virtio crypto devices
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO=n
+# Number of maximum virtio crypto devices
+CONFIG_RTE_MAX_VIRTIO_CRYPTO=32
+# Compile PMD for AESNI backed device
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
+# Compile PMD for Software backed device
+CONFIG_RTE_LIBRTE_PMD_OPENSSL=n
+# Compile PMD for AESNI GCM device
+CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n
+# Compile PMD for SNOW 3G device
+CONFIG_RTE_LIBRTE_PMD_SNOW3G=n
+CONFIG_RTE_LIBRTE_PMD_SNOW3G_DEBUG=n
+# Compile PMD for KASUMI device
+CONFIG_RTE_LIBRTE_PMD_KASUMI=n
+# Compile PMD for ZUC device
+CONFIG_RTE_LIBRTE_PMD_ZUC=n
+# Compile PMD for Crypto Scheduler device
+CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER=n
+# Compile PMD for NULL Crypto device
+CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO=n
+# Compile PMD for AMD CCP crypto device
+CONFIG_RTE_LIBRTE_PMD_CCP=n
+# Compile PMD for Marvell Crypto device
+CONFIG_RTE_LIBRTE_PMD_MVSAM_CRYPTO=n
+# Compile generic security library
+CONFIG_RTE_LIBRTE_SECURITY=n
+# Compile generic compression device library
+CONFIG_RTE_LIBRTE_COMPRESSDEV=n
+CONFIG_RTE_COMPRESS_MAX_DEVS=64
+# Compile compressdev unit test
+CONFIG_RTE_COMPRESSDEV_TEST=n
+# Compile PMD for Octeontx ZIPVF compression device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_ZIPVF=n
+# Compile PMD for ISA-L compression device
+CONFIG_RTE_LIBRTE_PMD_ISAL=n
+# Compile PMD for ZLIB compression device
+CONFIG_RTE_LIBRTE_PMD_ZLIB=n
+# Compile generic event device library
+CONFIG_RTE_LIBRTE_EVENTDEV=n
+CONFIG_RTE_LIBRTE_EVENTDEV_DEBUG=n
+CONFIG_RTE_EVENT_MAX_DEVS=16
+CONFIG_RTE_EVENT_MAX_QUEUES_PER_DEV=64
+CONFIG_RTE_EVENT_TIMER_ADAPTER_NUM_MAX=32
+CONFIG_RTE_EVENT_ETH_INTR_RING_SIZE=1024
+CONFIG_RTE_EVENT_CRYPTO_ADAPTER_MAX_INSTANCE=32
+CONFIG_RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE=32
+# Compile PMD for skeleton event device
+CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV=n
+CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV_DEBUG=n
+# Compile PMD for software event device
+CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV=n
+# Compile PMD for distributed software event device
+CONFIG_RTE_LIBRTE_PMD_DSW_EVENTDEV=n
+# Compile PMD for octeontx sso event device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF=n
+# Compile PMD for OPDL event device
+CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV=n
+# Compile PMD for NXP DPAA event device
+CONFIG_RTE_LIBRTE_PMD_DPAA_EVENTDEV=n
+# Compile PMD for NXP DPAA2 event device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=n
+# Compile raw device support
+# EXPERIMENTAL: API may change without prior notice
+CONFIG_RTE_LIBRTE_RAWDEV=n
+CONFIG_RTE_RAWDEV_MAX_DEVS=10
+CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=n
+# Compile PMD for NXP DPAA2 CMDIF raw device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=n
+# Compile PMD for NXP DPAA2 QDMA raw device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+# Compile PMD for Intel FPGA raw device
+CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=n
+# Compile librte_ring
+CONFIG_RTE_LIBRTE_RING=y
+# Compile librte_mempool
+CONFIG_RTE_LIBRTE_MEMPOOL=y
+CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
+CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
+# Compile Mempool drivers
+CONFIG_RTE_DRIVER_MEMPOOL_BUCKET=y
+CONFIG_RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB=64
+CONFIG_RTE_DRIVER_MEMPOOL_RING=y
+CONFIG_RTE_DRIVER_MEMPOOL_STACK=y
+# Compile PMD for octeontx fpa mempool device
+CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOOL=n
+# Compile librte_mbuf
+CONFIG_RTE_LIBRTE_MBUF=y
+CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
+CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="ring_mp_mc"
+CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
+CONFIG_RTE_PKTMBUF_HEADROOM=128
+# Compile librte_timer
+CONFIG_RTE_LIBRTE_TIMER=n
+CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
+# Compile librte_cfgfile
+CONFIG_RTE_LIBRTE_CFGFILE=n
+# Compile librte_cmdline
+CONFIG_RTE_LIBRTE_CMDLINE=y
+CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
+# Compile librte_hash
+CONFIG_RTE_LIBRTE_HASH=y
+CONFIG_RTE_LIBRTE_HASH_DEBUG=n
+# Compile librte_efd
+CONFIG_RTE_LIBRTE_EFD=n
+# Compile librte_member
+CONFIG_RTE_LIBRTE_MEMBER=y
+# Compile librte_jobstats
+CONFIG_RTE_LIBRTE_JOBSTATS=n
+# Compile architecture we compile for. device metrics library
+CONFIG_RTE_LIBRTE_METRICS=y
+# Compile architecture we compile for. bitrate statistics library
+CONFIG_RTE_LIBRTE_BITRATE=y
+# Compile architecture we compile for. latency statistics library
+CONFIG_RTE_LIBRTE_LATENCY_STATS=y
+# Compile librte_telemetry
+CONFIG_RTE_LIBRTE_TELEMETRY=n
+# Compile librte_lpm
+CONFIG_RTE_LIBRTE_LPM=n
+CONFIG_RTE_LIBRTE_LPM_DEBUG=n
+# Compile librte_acl
+CONFIG_RTE_LIBRTE_ACL=n
+CONFIG_RTE_LIBRTE_ACL_DEBUG=n
+# Compile librte_power
+CONFIG_RTE_LIBRTE_POWER=n
+CONFIG_RTE_LIBRTE_POWER_DEBUG=n
+CONFIG_RTE_MAX_LCORE_FREQS=64
+# Compile librte_net
+CONFIG_RTE_LIBRTE_NET=y
+# Compile librte_ip_frag
+CONFIG_RTE_LIBRTE_IP_FRAG=y
+CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
+CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
+CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
+# Compile GRO library
+CONFIG_RTE_LIBRTE_GRO=y
+# Compile GSO library
+CONFIG_RTE_LIBRTE_GSO=y
+# Compile librte_meter
+CONFIG_RTE_LIBRTE_METER=y
+# Compile librte_classify
+CONFIG_RTE_LIBRTE_FLOW_CLASSIFY=n
+# Compile librte_sched
+CONFIG_RTE_LIBRTE_SCHED=n
+CONFIG_RTE_SCHED_DEBUG=n
+CONFIG_RTE_SCHED_RED=n
+CONFIG_RTE_SCHED_COLLECT_STATS=n
+CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
+CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
+CONFIG_RTE_SCHED_VECTOR=n
+# Compile architecture we compile for. distributor library
+CONFIG_RTE_LIBRTE_DISTRIBUTOR=n
+# Compile architecture we compile for. reorder library
+CONFIG_RTE_LIBRTE_REORDER=n
+# Compile librte_port
+CONFIG_RTE_LIBRTE_PORT=n
+CONFIG_RTE_PORT_STATS_COLLECT=n
+CONFIG_RTE_PORT_PCAP=n
+# Compile librte_table
+CONFIG_RTE_LIBRTE_TABLE=n
+CONFIG_RTE_TABLE_STATS_COLLECT=n
+# Compile librte_pipeline
+CONFIG_RTE_LIBRTE_PIPELINE=n
+CONFIG_RTE_PIPELINE_STATS_COLLECT=n
+# Compile librte_kni
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_LIBRTE_PMD_KNI=n
+CONFIG_RTE_KNI_KMOD=n
+CONFIG_RTE_KNI_KMOD_ETHTOOL=n
+CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
+# Compile architecture we compile for. pdump library
+CONFIG_RTE_LIBRTE_PDUMP=y
+# Compile vhost user library
+CONFIG_RTE_LIBRTE_VHOST=y
+CONFIG_RTE_LIBRTE_VHOST_NUMA=y
+CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
+# Compile vhost PMD
+# To compile, CONFIG_RTE_LIBRTE_VHOST should be enabled.
+CONFIG_RTE_LIBRTE_PMD_VHOST=y
+# Compile IFC driver
+# To compile, CONFIG_RTE_LIBRTE_VHOST and CONFIG_RTE_EAL_VFIO
+# should be enabled.
+CONFIG_RTE_LIBRTE_IFC_PMD=n
+# Compile librte_bpf
+CONFIG_RTE_LIBRTE_BPF=n
+# allow load BPF from ELF files (requires libelf)
+CONFIG_RTE_LIBRTE_BPF_ELF=n
+# Compile architecture we compile for. test application
+CONFIG_RTE_APP_TEST=y
+CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
+# Compile architecture we compile for. procinfo application
+CONFIG_RTE_PROC_INFO=y
+# Compile architecture we compile for. PMD test application
+CONFIG_RTE_TEST_PMD=n
+CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
+CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+# Compile architecture we compile for. bbdev test application
+CONFIG_RTE_TEST_BBDEV=n
+# Compile architecture we compile for. crypto performance application
+CONFIG_RTE_APP_CRYPTO_PERF=n
+# Compile architecture we compile for. eventdev application
+CONFIG_RTE_APP_EVENTDEV=n
+CONFIG_RTE_EXEC_ENV_LINUXAPP=y
+CONFIG_RTE_LIBRTE_VHOST_POSTCOPY=n
+# Common libraries, before Bus/PMDs
+# NXP DPAA BUS and drivers
+# NXP FSLMC BUS and DPAA2 drivers
+# NXP ENETC PMD Driver
+CONFIG_RTE_ARCH_ARM64=y
+CONFIG_RTE_ARCH_64=y
+# Maximum available cache line size in arm64 implementations.
+# Setting to maximum available cache line size in generic config
+# to address minimum DMA alignment across all arm64 implementations.
+# Accelarate rte_memcpy. Be sure to run unit test (memcpy_perf_autotest)
+# to determine architecture we compile for. best threshold in code. Refer to notes in source file
+# (lib/librte_eal/common/include/arch/arm/rte_memcpy_64.h) for more info.
+CONFIG_RTE_ARCH_ARM64_MEMCPY=n
+#CONFIG_RTE_ARM64_MEMCPY_ALIGNED_THRESHOLD=2048
+#CONFIG_RTE_ARM64_MEMCPY_UNALIGNED_THRESHOLD=512
+# Leave below RTE_ARM64_MEMCPY_xxx options commented out, unless there're
+# strong reasons.
+#CONFIG_RTE_ARM64_MEMCPY_SKIP_GCC_VER_CHECK=n
+#CONFIG_RTE_ARM64_MEMCPY_ALIGN_MASK=0xF
+#CONFIG_RTE_ARM64_MEMCPY_STRICT_ALIGN=n
+CONFIG_RTE_TOOLCHAIN_GCC=y
+CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
diff --git a/SOURCES/configlib.sh b/SOURCES/configlib.sh
new file mode 100644
index 0000000..a1049b3
--- /dev/null
+++ b/SOURCES/configlib.sh
@@ -0,0 +1,105 @@
+# Copyright (C) 2017, Red Hat, Inc.
+#
+# Core configuration file library.
+
+# Configurations are determined by sha values.  The way to determine is by
+# the special text:
+# $FILE_COMMENT_TYPE -*- cfg-sha: $SHA256 -*-
+
+export LC_ALL=C
+
+# check required binaries
+__check_reqd_binaries() {
+    local BIN __binaries=("egrep" "sort" "sha256sum" "sed")
+    for BIN in $__binaries; do
+        if ! type -P $BIN >/dev/null 2>&1; then
+            echo "Binary $BIN not found.  Please install."
+            exit 1
+        fi
+    done
+}
+
+# Calculates a sha from a file
+# The algorithm for generating a sha from a config is thus:
+#
+# 1. Remove all comment lines and blank lines
+# 2. Sort the content
+# 3. generate the sha-256 sum
+#
+# From a script perspective, this means:
+#   egrep -v ^\# %file% | egrep -v ^$ | sort -u | sha256sum
+#
+# Params:
+#  $1 = output variable
+#  $2 = file to use to calculate the shasum
+#  $3 = file comment type (defaults to # if unspecified)
+calc_sha() {
+    __check_reqd_binaries
+
+    if [ "$1" == "" ]; then
+        echo "Please pass in a storage variable."
+        return 1
+    fi
+
+    local __resultvar=$1
+    __retval=1
+    shift
+
+    local __file=$1
+    local cmnt=${2:-#}
+
+    if [ -f "$__file" ]; then
+        local __shasum=$(egrep -v ^"$cmnt" "$__file" | egrep -v ^$ | sort -u | sha256sum -t | cut -d" " -f1)
+        eval $__resultvar="'$__shasum'"
+        __retval=0
+    fi
+    return $__retval
+}
+
+# Retrieves a sha stored in a file
+# Param:
+#  $1 = output variable
+#  $2 = file to use to calculate the shasum
+#  $3 = file comment type (defaults to # if unspecified)
+retr_sha() {
+    __check_reqd_binaries
+
+    if [ "$1" == "" ]; then
+        echo "Please pass in a storage variable."
+        return 1
+    fi
+
+    local __resultvar=$1
+    __retval=1
+    shift
+
+    local __file=$1
+    local cmnt=${2:-#}
+
+    if [ -f "$__file" ]; then
+        if grep -q "$cmnt -\*- cfg-sha:" "$__file"; then
+            local __shasum=$(grep "$cmnt -\*- cfg-sha:" "$__file" | sed -e "s@$cmnt -\*- cfg-sha: @@" | cut -d" " -f1)
+            eval $__resultvar="'$__shasum'"
+            __retval=0
+        fi
+    fi
+    return $__retval
+}
+
+
+# Set a config value
+# set_conf dpdk_build_tree parameter value
+# dpdk_build_tree is the directory where the .config lives
+# parameter is the config parameter
+# value is the value to set for the config parameter
+set_conf() {
+    c="$1/.config"
+    shift
+
+    if grep -q "$1" "$c"; then
+        sed -i "s:^$1=.*$:$1=$2:g" $c
+    else
+        echo $1=$2 >> "$c"
+    fi
+}
+
diff --git a/SOURCES/gen_config_group.sh b/SOURCES/gen_config_group.sh
new file mode 100755
index 0000000..d1c06fe
--- /dev/null
+++ b/SOURCES/gen_config_group.sh
@@ -0,0 +1,216 @@
+#!/bin/bash
+
+source configlib.sh
+
+# Generates arch configurations in the current directory based on
+# 1. an openvswitch.spec file
+# 2. an expanded dpdk tree
+
+if (( $# != 2 )); then
+    echo "$0: openvswitch.spec dpdk_tree" >&2
+    exit 1
+fi
+
+OVSSPEC="$1"
+DPDKDIR="$2"
+
+# accumulate all arch + name triples
+OVS_DPDK_CONF_MACH_ARCH=()
+for arch in $(grep %define\ dpdk_mach_arch "$OVSSPEC" | sed 's@%define dpdk_mach_arch @@')
+do
+    OVS_DPDK_CONF_MACH_ARCH+=($arch)
+done
+
+OVS_DPDK_CONF_MACH_TMPL=()
+for tmpl in $(grep %define\ dpdk_mach_tmpl "$OVSSPEC" | sed 's@%define dpdk_mach_tmpl @@')
+do
+    OVS_DPDK_CONF_MACH_TMPL+=($tmpl)
+done
+
+OVS_DPDK_CONF_MACH=()
+for mach in $(grep %define\ dpdk_mach\  "$OVSSPEC" | sed 's@%define dpdk_mach @@')
+do
+    OVS_DPDK_CONF_MACH+=($mach)
+done
+
+OVS_DPDK_TARGETS=()
+for ((i=0; i < ${#OVS_DPDK_CONF_MACH[@]}; i++));
+do
+    OVS_DPDK_TARGETS+=("${OVS_DPDK_CONF_MACH_ARCH[$i]}-${OVS_DPDK_CONF_MACH_TMPL[$i]}-linuxapp-gcc")
+    echo "DPDK-target: ${OVS_DPDK_TARGETS[$i]}"
+done
+
+OUTPUT_DIR=$(pwd)
+pushd "$DPDKDIR"
+for ((i=0; i < ${#OVS_DPDK_TARGETS[@]}; i++));
+do
+    echo "For ${OVS_DPDK_TARGETS[$i]}:"
+
+    echo "     a. Generating initial config"
+    echo "        make V=1 T=${OVS_DPDK_TARGETS[$i]} O=${OVS_DPDK_TARGETS[$i]}"
+    make V=1 T=${OVS_DPDK_TARGETS[$i]} O=${OVS_DPDK_TARGETS[$i]} -j8 config
+    ORIG_SHA=""
+    OUTDIR="${OVS_DPDK_TARGETS[$i]}"
+
+    echo "     b. calculating and applying sha"
+    calc_sha ORIG_SHA "${OUTDIR}/.config"
+    if [ "$ORIG_SHA" == "" ]; then
+        echo "ERROR: Unable to get sha for arch ${OVS_DPDK_TARGETS[$i]}"
+        exit 1
+    fi
+    echo "# -*- cfg-sha: ${ORIG_SHA}" > ${OUTDIR}/.config.new
+    cat "${OUTDIR}/.config" >> "${OUTDIR}/.config.new"
+    cp "${OUTDIR}/.config" "${OUTDIR}/.config.orig"
+    mv -f "${OUTDIR}/.config.new" "${OUTDIR}/.config"
+
+    echo "     c. setting initial configurations"
+    # these are the original setconf values from openvswitch.spec
+    set_conf "${OUTDIR}" CONFIG_RTE_MACHINE "\\\"${OVS_DPDK_CONF_MACH[$i]}\\\""
+
+    # Disable DPDK libraries not needed
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_TIMER n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_CFGFILE n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_JOBSTATS n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_LPM n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_ACL n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_POWER n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_SCHED n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_DISTRIBUTOR n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_REORDER n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PORT n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_TABLE n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PIPELINE n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_KNI n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_CRYPTODEV n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_SECURITY n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_FLOW_CLASSIFY n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_BBDEV n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_COMPRESSDEV n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_BPF n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOOL n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_DPAA_MEMPOOL n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_CFGFILE n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_EFD n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_FLOW_CLASSIFY n
+
+    # Disable all eventdevs
+    for eventdev in $(grep _EVENTDEV= "${OUTDIR}/.config" | sed 's@=\(y\|n\)@@g')
+    do
+        set_conf "${OUTDIR}" $eventdev n
+    done
+
+    # Disable all rawdevs
+    for rawdev in $(grep _RAWDEV= "${OUTDIR}/.config" | sed 's@=\(y\|n\)@@g')
+    do
+        set_conf "${OUTDIR}" $rawdev n
+    done
+
+    # Disable virtio user
+    set_conf "${OUTDIR}" CONFIG_RTE_VIRTIO_USER n
+
+    # Enable vhost numa as libnuma dep is ok
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_VHOST_NUMA y
+
+    # start by disabling ALL PMDs
+    for pmd in $(grep _PMD= "${OUTDIR}/.config" | sed 's@=\(y\|n\)@@g')
+    do
+        set_conf "${OUTDIR}" $pmd n
+    done
+
+    # PMDs which have their own naming scheme
+    # the default for this was 'n' at one point.  Make sure we keep it
+    # as such
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_QAT n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_OCTEONTX_ZIPVF n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_VHOST n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_KNI n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_XENVIRT n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_NULL n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_PCAP n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_BOND n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_AF_PACKET n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_SOFTNIC n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_DPAA_SEC n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_COMMON_DPAAX n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_CAAM_JR n
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_CAAM_JR_BE n
+
+    # whitelist of enabled PMDs
+    # Soft PMDs to enable
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_RING y
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_VHOST y
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_VIRTIO_PMD y
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_TAP y
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PMD_FAILSAFE y
+
+
+    # start by disabling all buses
+    for bus in $(grep _BUS= "${OUTDIR}/.config" | sed 's@=\(y\|n\)@@g')
+    do
+        set_conf "${OUTDIR}" $bus n
+    done
+
+    # blacklist buses that don't conform to std naming
+    # May override VMBUS later in arch specific section
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_VMBUS n
+
+    # whitelist buses
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_PCI_BUS y
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_VDEV_BUS y
+
+
+    # Disable some other miscellanous items related to test apps
+    set_conf "${OUTDIR}" CONFIG_RTE_TEST_BBDEV n
+    set_conf "${OUTDIR}" CONFIG_RTE_APP_CRYPTO_PERF n
+
+    # Disable kernel modules
+    set_conf "${OUTDIR}" CONFIG_RTE_EAL_IGB_UIO n
+    set_conf "${OUTDIR}" CONFIG_RTE_KNI_KMOD n
+
+    # Disable experimental stuff
+    set_conf "${OUTDIR}" CONFIG_RTE_NEXT_ABI n
+
+    # Arch specific
+    set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_I40E_PMD y
+    case "${OVS_DPDK_CONF_MACH_ARCH[i]}" in
+    x86_64)
+        # Hw PMD
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_BNXT_PMD y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_ENIC_PMD y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_MLX4_PMD y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_MLX5_PMD y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_NFP_PMD y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_QEDE_PMD y
+        # Sw PMD
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_NETVSC_PMD y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD y
+        # Bus
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_VMBUS y
+        ;&
+    arm64)
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_IXGBE_PMD y
+        set_conf "${OUTDIR}" CONFIG_RTE_LIBRTE_IGB_PMD y
+        ;;
+    esac
+
+    cp "${OUTDIR}/.config" "${OUTPUT_DIR}/${OVS_DPDK_TARGETS[$i]}-config"
+done
+popd >/dev/null
+
+printf "For each arch ( "
+for ((i=0; i < ${#OVS_DPDK_CONF_MACH_ARCH[@]}; i++));
+do
+    printf "${OVS_DPDK_CONF_MACH_ARCH[i]} "
+done
+echo "):"
+echo "1. ensure you enable the requisite hw"
diff --git a/SOURCES/ovn22.03.patch b/SOURCES/ovn22.03.patch
new file mode 100644
index 0000000..ef85019
--- /dev/null
+++ b/SOURCES/ovn22.03.patch
@@ -0,0 +1,1351 @@
+diff --git a/AUTHORS.rst b/AUTHORS.rst
+index 8572c24c8..d3747f8d1 100644
+--- a/AUTHORS.rst
++++ b/AUTHORS.rst
+@@ -147,6 +147,7 @@ Fabrizio D'Angelo                  fdangelo@redhat.com
+ Flavio Fernandes                   flavio@flaviof.com
+ Flavio Leitner                     fbl@redhat.com
+ Francesco Fusco                    ffusco@redhat.com
++François Rigault                   frigo@amadeus.com
+ Frank Wang                         wangpeihuixyz@126.com
+ Frédéric Tobias Christ             fchrist@live.de
+ Frode Nordahl                      frode.nordahl@gmail.com
+diff --git a/NEWS b/NEWS
+index 9f3ce3cf3..15fa545d2 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,4 +1,7 @@
+-OVN v22.03.0 - XX XXX XXXX
++OVN v22.03.1 - xx xxx xxxx
++--------------------------
++
++OVN v22.03.0 - 11 Mar 2022
+ --------------------------
+   - Refactor CoPP commands introducing a unique name index in CoPP NB table.
+     Add following new CoPP commands to manage CoPP table:
+diff --git a/configure.ac b/configure.ac
+index 283381b4e..70f86e1f5 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -13,7 +13,7 @@
+ # limitations under the License.
+ 
+ AC_PREREQ(2.63)
+-AC_INIT(ovn, 22.03.0, bugs@openvswitch.org)
++AC_INIT(ovn, 22.03.1, bugs@openvswitch.org)
+ AC_CONFIG_MACRO_DIR([m4])
+ AC_CONFIG_AUX_DIR([build-aux])
+ AC_CONFIG_HEADERS([config.h])
+diff --git a/controller-vtep/binding.c b/controller-vtep/binding.c
+index 01d5a16d2..1ee52b592 100644
+--- a/controller-vtep/binding.c
++++ b/controller-vtep/binding.c
+@@ -109,12 +109,10 @@ update_pb_chassis(const struct sbrec_port_binding *port_binding_rec,
+                      port_binding_rec->chassis->name,
+                      chassis_rec->name);
+         }
+-
+         sbrec_port_binding_set_chassis(port_binding_rec, chassis_rec);
+-        if (port_binding_rec->n_up) {
+-            bool up = true;
+-            sbrec_port_binding_set_up(port_binding_rec, &up, 1);
+-        }
++    } else if (port_binding_rec->n_up) {
++        bool up = true;
++        sbrec_port_binding_set_up(port_binding_rec, &up, 1);
+     }
+ }
+ 
+diff --git a/controller/binding.c b/controller/binding.c
+index 4d62b0858..1259e6b3b 100644
+--- a/controller/binding.c
++++ b/controller/binding.c
+@@ -481,6 +481,16 @@ remove_related_lport(const struct sbrec_port_binding *pb,
+     }
+ }
+ 
++static void
++delete_active_pb_ras_pd(const struct sbrec_port_binding *pb,
++                        struct shash *ras_pd_map)
++{
++    struct pb_ld_binding *ras_pd =
++        shash_find_and_delete(ras_pd_map, pb->logical_port);
++
++    free(ras_pd);
++}
++
+ static void
+ update_active_pb_ras_pd(const struct sbrec_port_binding *pb,
+                         struct hmap *local_datapaths,
+@@ -2251,6 +2261,9 @@ binding_handle_port_binding_changes(struct binding_ctx_in *b_ctx_in,
+             continue;
+         }
+ 
++        delete_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ipv6_pd);
++        delete_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ras);
++
+         enum en_lport_type lport_type = get_lport_type(pb);
+ 
+         struct binding_lport *b_lport =
+diff --git a/controller/ofctrl.c b/controller/ofctrl.c
+index a7c2d2011..3b9d71733 100644
+--- a/controller/ofctrl.c
++++ b/controller/ofctrl.c
+@@ -943,7 +943,12 @@ link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
+             break;
+         }
+     }
+-    ovs_list_insert(&f->installed_ref_list_node, &d->installed_ref_list_node);
++    if (!f) {
++        ovs_list_insert(&i->desired_refs, &d->installed_ref_list_node);
++    } else {
++        ovs_list_insert(&f->installed_ref_list_node,
++                        &d->installed_ref_list_node);
++    }
+     d->installed_flow = i;
+     return installed_flow_get_active(i) == d;
+ }
+@@ -2324,7 +2329,20 @@ deleted_flow_lookup(struct hmap *deleted_flows, struct ovn_flow *target)
+             && f->cookie == target->cookie
+             && ofpacts_equal(f->ofpacts, f->ofpacts_len, target->ofpacts,
+                              target->ofpacts_len)) {
+-            return d;
++            /* del_f must have been installed, otherwise it should have
++             * been removed during track_flow_del. */
++            ovs_assert(d->installed_flow);
++
++            /* Now we also need to make sure the desired flow being
++             * added/updated has exact same action and cookie as the installed
++             * flow of d. Otherwise, don't merge them, so that the
++             * installed flow can be updated later. */
++            struct ovn_flow *f_i = &d->installed_flow->flow;
++            if (f_i->cookie == target->cookie
++                && ofpacts_equal(f_i->ofpacts, f_i->ofpacts_len,
++                                 target->ofpacts, target->ofpacts_len)) {
++                return d;
++            }
+         }
+     }
+     return NULL;
+@@ -2353,10 +2371,6 @@ merge_tracked_flows(struct ovn_desired_flow_table *flow_table)
+                 continue;
+             }
+ 
+-            /* del_f must have been installed, otherwise it should have been
+-             * removed during track_flow_add_or_modify. */
+-            ovs_assert(del_f->installed_flow);
+-
+             if (!f->installed_flow) {
+                 /* f is not installed yet. */
+                 replace_installed_to_desired(del_f->installed_flow, del_f, f);
+@@ -2665,6 +2679,13 @@ ofctrl_put(struct ovn_desired_flow_table *lflow_table,
+     EXTEND_TABLE_FOR_EACH_INSTALLED (m_installed, next_meter, meters) {
+         /* Delete the meter. */
+         ofctrl_meter_bands_erase(m_installed, &msgs);
++        if (!strncmp(m_installed->name, "__string: ", 10)) {
++            struct ofputil_meter_mod mm = {
++                .command = OFPMC13_DELETE,
++                .meter = { .meter_id = m_installed->table_id },
++            };
++            add_meter_mod(&mm, &msgs);
++        }
+         ovn_extend_table_remove_existing(meters, m_installed);
+     }
+ 
+diff --git a/controller/pinctrl.c b/controller/pinctrl.c
+index 25b37ee88..2f718aca7 100644
+--- a/controller/pinctrl.c
++++ b/controller/pinctrl.c
+@@ -5523,7 +5523,7 @@ get_localnet_vifs_l3gwports(
+             }
+             const struct sbrec_port_binding *pb
+                 = lport_lookup_by_name(sbrec_port_binding_by_name, iface_id);
+-            if (!pb) {
++            if (!pb || pb->chassis != chassis) {
+                 continue;
+             }
+             struct local_datapath *ld
+@@ -5554,7 +5554,7 @@ get_localnet_vifs_l3gwports(
+         sbrec_port_binding_index_set_datapath(target, ld->datapath);
+         SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
+                                            sbrec_port_binding_by_datapath) {
+-            if (!strcmp(pb->type, "l3gateway")
++            if ((!strcmp(pb->type, "l3gateway") && pb->chassis == chassis)
+                 || !strcmp(pb->type, "patch")) {
+                 sset_add(local_l3gw_ports, pb->logical_port);
+             }
+@@ -5781,7 +5781,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
+         const struct sbrec_port_binding *pb = lport_lookup_by_name(
+             sbrec_port_binding_by_name, iface_id);
+         if (pb) {
+-            send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
++            send_garp_rarp_update(ovnsb_idl_txn,
++                                  sbrec_mac_binding_by_lport_ip,
+                                   local_datapaths, pb, &nat_addresses);
+         }
+     }
+diff --git a/debian/changelog b/debian/changelog
+index f1167591b..18a1a042e 100644
+--- a/debian/changelog
++++ b/debian/changelog
+@@ -1,3 +1,9 @@
++OVN (22.03.1-1) unstable; urgency=low
++   [ OVN team ]
++   * New upstream version
++
++ -- OVN team <dev@openvswitch.org>  Fri, 11 Mar 2022 13:22:32 -0500
++
+ ovn (22.03.0-1) unstable; urgency=low
+ 
+    * New upstream version
+diff --git a/lib/actions.c b/lib/actions.c
+index 5d3caaf2b..2219c5b37 100644
+--- a/lib/actions.c
++++ b/lib/actions.c
+@@ -2336,7 +2336,7 @@ validate_empty_lb_backends(struct action_context *ctx,
+ 
+         switch (o->option->code) {
+         case EMPTY_LB_VIP:
+-            if (!inet_parse_active(c->string, 0, &ss, false)) {
++            if (!inet_parse_active(c->string, 0, &ss, false, NULL)) {
+                 lexer_error(ctx->lexer, "Invalid load balancer VIP '%s'",
+                             c->string);
+                 return;
+diff --git a/lib/expr.c b/lib/expr.c
+index 47ef6108e..058390a16 100644
+--- a/lib/expr.c
++++ b/lib/expr.c
+@@ -211,16 +211,17 @@ expr_combine(enum expr_type type, struct expr *a, struct expr *b)
+ }
+ 
+ static void
+-expr_insert_andor(struct expr *andor, struct expr *before, struct expr *new)
++expr_insert_andor(struct expr *andor, struct ovs_list *before,
++                  struct expr *new)
+ {
+     if (new->type == andor->type) {
+         if (andor->type == EXPR_T_AND) {
+             /* Conjunction junction, what's your function? */
+         }
+-        ovs_list_splice(&before->node, new->andor.next, &new->andor);
++        ovs_list_splice(before, new->andor.next, &new->andor);
+         expr_destroy(new);
+     } else {
+-        ovs_list_insert(&before->node, &new->node);
++        ovs_list_insert(before, &new->node);
+     }
+ }
+ 
+@@ -2101,7 +2102,8 @@ expr_annotate__(struct expr *expr, const struct shash *symtab,
+                 expr_destroy(expr);
+                 return NULL;
+             }
+-            expr_insert_andor(expr, next, new_sub);
++            expr_insert_andor(expr, next ? &next->node : &expr->andor,
++                              new_sub);
+         }
+         *errorp = NULL;
+         return expr;
+@@ -2301,7 +2303,7 @@ expr_evaluate_condition(struct expr *expr,
+             struct expr *e = expr_evaluate_condition(sub, is_chassis_resident,
+                                                      c_aux);
+             e = expr_fix(e);
+-            expr_insert_andor(expr, next, e);
++            expr_insert_andor(expr, next ? &next->node : &expr->andor, e);
+         }
+         return expr_fix(expr);
+ 
+@@ -2334,7 +2336,8 @@ expr_simplify(struct expr *expr)
+     case EXPR_T_OR:
+         LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
+             ovs_list_remove(&sub->node);
+-            expr_insert_andor(expr, next, expr_simplify(sub));
++            expr_insert_andor(expr, next ? &next->node : &expr->andor,
++                              expr_simplify(sub));
+         }
+         return expr_fix(expr);
+ 
+@@ -2444,12 +2447,13 @@ crush_and_string(struct expr *expr, const struct expr_symbol *symbol)
+      * EXPR_T_OR with EXPR_T_CMP subexpressions. */
+     struct expr *sub, *next = NULL;
+     LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
++        struct ovs_list *next_list = next ? &next->node : &expr->andor;
+         ovs_list_remove(&sub->node);
+         struct expr *new = crush_cmps(sub, symbol);
+         switch (new->type) {
+         case EXPR_T_CMP:
+             if (!singleton) {
+-                ovs_list_insert(&next->node, &new->node);
++                ovs_list_insert(next_list, &new->node);
+                 singleton = new;
+             } else {
+                 bool match = !strcmp(new->cmp.string, singleton->cmp.string);
+@@ -2463,7 +2467,7 @@ crush_and_string(struct expr *expr, const struct expr_symbol *symbol)
+         case EXPR_T_AND:
+             OVS_NOT_REACHED();
+         case EXPR_T_OR:
+-            ovs_list_insert(&next->node, &new->node);
++            ovs_list_insert(next_list, &new->node);
+             break;
+         case EXPR_T_BOOLEAN:
+             if (!new->boolean) {
+@@ -2559,7 +2563,7 @@ crush_and_numeric(struct expr *expr, const struct expr_symbol *symbol)
+         case EXPR_T_AND:
+             OVS_NOT_REACHED();
+         case EXPR_T_OR:
+-            ovs_list_insert(&next->node, &new->node);
++            ovs_list_insert(next ? &next->node : &expr->andor, &new->node);
+             break;
+         case EXPR_T_BOOLEAN:
+             if (!new->boolean) {
+@@ -2725,7 +2729,8 @@ crush_or(struct expr *expr, const struct expr_symbol *symbol)
+      * is now a disjunction of cmps over the same symbol. */
+     LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) {
+         ovs_list_remove(&sub->node);
+-        expr_insert_andor(expr, next, crush_cmps(sub, symbol));
++        expr_insert_andor(expr, next ? &next->node : &expr->andor,
++                          crush_cmps(sub, symbol));
+     }
+     expr = expr_fix(expr);
+     if (expr->type != EXPR_T_OR) {
+@@ -2886,8 +2891,7 @@ expr_normalize_and(struct expr *expr)
+ 
+     struct expr *a, *b;
+     LIST_FOR_EACH_SAFE (a, b, node, &expr->andor) {
+-        if (&b->node == &expr->andor
+-            || a->type != EXPR_T_CMP || b->type != EXPR_T_CMP
++        if (!b || a->type != EXPR_T_CMP || b->type != EXPR_T_CMP
+             || a->cmp.symbol != b->cmp.symbol) {
+             continue;
+         } else if (a->cmp.symbol->width
+@@ -2964,7 +2968,8 @@ expr_normalize_or(struct expr *expr)
+                 }
+                 expr_destroy(new);
+             } else {
+-                expr_insert_andor(expr, next, new);
++                expr_insert_andor(expr, next ? &next->node : &expr->andor,
++                                  new);
+             }
+         } else {
+             ovs_assert(sub->type == EXPR_T_CMP ||
+diff --git a/lib/inc-proc-eng.c b/lib/inc-proc-eng.c
+index 7b4391700..575b774ae 100644
+--- a/lib/inc-proc-eng.c
++++ b/lib/inc-proc-eng.c
+@@ -354,14 +354,11 @@ engine_recompute(struct engine_node *node, bool allowed,
+                  const char *reason_fmt, ...)
+ {
+     char *reason = NULL;
++    va_list reason_args;
+ 
+-    if (VLOG_IS_DBG_ENABLED()) {
+-        va_list reason_args;
+-
+-        va_start(reason_args, reason_fmt);
+-        reason = xvasprintf(reason_fmt, reason_args);
+-        va_end(reason_args);
+-    }
++    va_start(reason_args, reason_fmt);
++    reason = xvasprintf(reason_fmt, reason_args);
++    va_end(reason_args);
+ 
+     if (!allowed) {
+         VLOG_DBG("node: %s, recompute (%s) aborted", node->name, reason);
+diff --git a/lib/ovn-parallel-hmap.h b/lib/ovn-parallel-hmap.h
+index 897208ef8..0f7d68770 100644
+--- a/lib/ovn-parallel-hmap.h
++++ b/lib/ovn-parallel-hmap.h
+@@ -58,11 +58,11 @@ extern "C" {
+  * ThreadID + step * i as the JOBID parameter.
+  */
+ 
+-#define HMAP_FOR_EACH_IN_PARALLEL(NODE, MEMBER, JOBID, HMAP) \
+-   for (INIT_CONTAINER(NODE, hmap_first_in_bucket_num(HMAP, JOBID), MEMBER); \
+-        (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \
+-       || ((NODE = NULL), false); \
+-       ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER))
++#define HMAP_FOR_EACH_IN_PARALLEL(NODE, MEMBER, JOBID, HMAP)                \
++   for (INIT_MULTIVAR(NODE, MEMBER, hmap_first_in_bucket_num(HMAP, JOBID),  \
++                      struct hmap_node);                                    \
++        CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL);           \
++        UPDATE_MULTIVAR(NODE, hmap_next_in_bucket(ITER_VAR(NODE))))
+ 
+ /* We do not have a SAFE version of the macro, because the hash size is not
+  * atomic and hash removal operations would need to be wrapped with
+diff --git a/lib/ovn-util.c b/lib/ovn-util.c
+index a22ae84fe..2f2f7ae39 100644
+--- a/lib/ovn-util.c
++++ b/lib/ovn-util.c
+@@ -735,7 +735,7 @@ ip_address_and_port_from_lb_key(const char *key, char **ip_address,
+                                 uint16_t *port, int *addr_family)
+ {
+     struct sockaddr_storage ss;
+-    if (!inet_parse_active(key, 0, &ss, false)) {
++    if (!inet_parse_active(key, 0, &ss, false, NULL)) {
+         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+         VLOG_WARN_RL(&rl, "bad ip address or port for load balancer key %s",
+                      key);
+diff --git a/northd/northd.c b/northd/northd.c
+index b22da67e9..217f180eb 100644
+--- a/northd/northd.c
++++ b/northd/northd.c
+@@ -763,16 +763,6 @@ init_nat_entries(struct ovn_datapath *od)
+         return;
+     }
+ 
+-    if (od->n_l3dgw_ports > 1) {
+-        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+-        VLOG_WARN_RL(&rl, "NAT is configured on logical router %s, which has %"
+-                     PRIuSIZE" distributed gateway ports. NAT is not supported"
+-                     " yet when there is more than one distributed gateway "
+-                     "port on the router.",
+-                     od->nbr->name, od->n_l3dgw_ports);
+-        return;
+-    }
+-
+     od->nat_entries = xmalloc(od->nbr->n_nat * sizeof *od->nat_entries);
+ 
+     for (size_t i = 0; i < od->nbr->n_nat; i++) {
+@@ -6418,6 +6408,72 @@ ovn_port_group_destroy(struct hmap *pgs, struct ovn_port_group *pg)
+     }
+ }
+ 
++static void
++copy_ra_to_sb(struct ovn_port *op, const char *address_mode);
++
++static void
++ovn_update_ipv6_options(struct hmap *ports)
++{
++    struct ovn_port *op;
++    HMAP_FOR_EACH (op, key_node, ports) {
++        if (!op->nbrp || op->nbrp->peer || !op->peer) {
++            continue;
++        }
++
++        if (!op->lrp_networks.n_ipv6_addrs) {
++            continue;
++        }
++
++        struct smap options;
++        smap_clone(&options, &op->sb->options);
++
++        /* enable IPv6 prefix delegation */
++        bool prefix_delegation = smap_get_bool(&op->nbrp->options,
++                                           "prefix_delegation", false);
++        if (!lrport_is_enabled(op->nbrp)) {
++            prefix_delegation = false;
++        }
++        if (smap_get_bool(&options, "ipv6_prefix_delegation",
++                          false) != prefix_delegation) {
++            smap_add(&options, "ipv6_prefix_delegation",
++                     prefix_delegation ? "true" : "false");
++        }
++
++        bool ipv6_prefix = smap_get_bool(&op->nbrp->options,
++                                     "prefix", false);
++        if (!lrport_is_enabled(op->nbrp)) {
++            ipv6_prefix = false;
++        }
++        if (smap_get_bool(&options, "ipv6_prefix", false) != ipv6_prefix) {
++            smap_add(&options, "ipv6_prefix",
++                     ipv6_prefix ? "true" : "false");
++        }
++        sbrec_port_binding_set_options(op->sb, &options);
++
++        smap_destroy(&options);
++
++        const char *address_mode = smap_get(
++            &op->nbrp->ipv6_ra_configs, "address_mode");
++
++        if (!address_mode) {
++            continue;
++        }
++        if (strcmp(address_mode, "slaac") &&
++            strcmp(address_mode, "dhcpv6_stateful") &&
++            strcmp(address_mode, "dhcpv6_stateless")) {
++            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
++            VLOG_WARN_RL(&rl, "Invalid address mode [%s] defined",
++                         address_mode);
++            continue;
++        }
++
++        if (smap_get_bool(&op->nbrp->ipv6_ra_configs, "send_periodic",
++                          false)) {
++            copy_ra_to_sb(op, address_mode);
++        }
++    }
++}
++
+ static void
+ build_port_group_lswitches(struct northd_input *input_data,
+                            struct hmap *pgs,
+@@ -10759,6 +10815,12 @@ build_neigh_learning_flows_for_lrouter(
+                           copp_meter_get(COPP_ARP, od->nbr->copp,
+                                          meter_groups));
+ 
++        ovn_lflow_metered(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 95,
++                          "nd_na && nd.tll == 0",
++                          "put_nd(inport, nd.target, eth.src); next;",
++                          copp_meter_get(COPP_ND_NA, od->nbr->copp,
++                                         meter_groups));
++
+         ovn_lflow_metered(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90,
+                           "nd_na", "put_nd(inport, nd.target, nd.tll); next;",
+                           copp_meter_get(COPP_ND_NA, od->nbr->copp,
+@@ -10851,34 +10913,6 @@ build_ND_RA_flows_for_lrouter_port(
+         return;
+     }
+ 
+-    struct smap options;
+-    smap_clone(&options, &op->sb->options);
+-
+-    /* enable IPv6 prefix delegation */
+-    bool prefix_delegation = smap_get_bool(&op->nbrp->options,
+-                                           "prefix_delegation", false);
+-    if (!lrport_is_enabled(op->nbrp)) {
+-        prefix_delegation = false;
+-    }
+-    if (smap_get_bool(&options, "ipv6_prefix_delegation",
+-                      false) != prefix_delegation) {
+-        smap_add(&options, "ipv6_prefix_delegation",
+-                 prefix_delegation ? "true" : "false");
+-    }
+-
+-    bool ipv6_prefix = smap_get_bool(&op->nbrp->options,
+-                                     "prefix", false);
+-    if (!lrport_is_enabled(op->nbrp)) {
+-        ipv6_prefix = false;
+-    }
+-    if (smap_get_bool(&options, "ipv6_prefix", false) != ipv6_prefix) {
+-        smap_add(&options, "ipv6_prefix",
+-                 ipv6_prefix ? "true" : "false");
+-    }
+-    sbrec_port_binding_set_options(op->sb, &options);
+-
+-    smap_destroy(&options);
+-
+     const char *address_mode = smap_get(
+         &op->nbrp->ipv6_ra_configs, "address_mode");
+ 
+@@ -10894,11 +10928,6 @@ build_ND_RA_flows_for_lrouter_port(
+         return;
+     }
+ 
+-    if (smap_get_bool(&op->nbrp->ipv6_ra_configs, "send_periodic",
+-                      false)) {
+-        copy_ra_to_sb(op, address_mode);
+-    }
+-
+     ds_clear(match);
+     ds_put_format(match, "inport == %s && ip6.dst == ff02::2 && nd_rs",
+                           op->json_key);
+@@ -12805,6 +12834,7 @@ build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od,
+             ds_put_format(actions, "ip%s.src=%s; next;",
+                           is_v6 ? "6" : "4", nat->external_ip);
+         } else {
++            ds_put_format(match, " && (!ct.trk || !ct.rpl)");
+             ds_put_format(actions, "ct_snat(%s", nat->external_ip);
+ 
+             if (nat->external_port_range[0]) {
+@@ -13155,6 +13185,18 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows,
+         return;
+     }
+ 
++    /* NAT rules are not currently supported on logical routers with multiple
++     * distributed gateway ports. */
++    if (od->n_l3dgw_ports > 1) {
++        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
++        VLOG_WARN_RL(&rl, "NAT is configured on logical router %s, which has %"
++                     PRIuSIZE" distributed gateway ports. NAT is not supported"
++                     " yet when there is more than one distributed gateway "
++                     "port on the router.",
++                     od->nbr->name, od->n_l3dgw_ports);
++        return;
++    }
++
+     struct sset nat_entries = SSET_INITIALIZER(&nat_entries);
+ 
+     bool dnat_force_snat_ip =
+@@ -15048,6 +15090,7 @@ ovnnb_db_run(struct northd_input *input_data,
+     build_meter_groups(input_data, &data->meter_groups);
+     stopwatch_stop(BUILD_LFLOWS_CTX_STOPWATCH_NAME, time_msec());
+     stopwatch_start(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, time_msec());
++    ovn_update_ipv6_options(&data->ports);
+     ovn_update_ipv6_prefix(&data->ports);
+ 
+     sync_address_sets(input_data,  ovnsb_txn, &data->datapaths);
+diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
+index 1c9d408af..4cb70e185 100644
+--- a/northd/ovn-northd.8.xml
++++ b/northd/ovn-northd.8.xml
+@@ -2301,6 +2301,12 @@ next;
+         <code>put_arp(inport, arp.spa, arp.sha); next;</code>
+       </li>
+ 
++      <li>
++        A priority-95 flow with the match <code>nd_na  &amp;&amp;
++        nd.tll == 0</code> and applies the action
++        <code>put_nd(inport, nd.target, eth.src); next;</code>
++      </li>
++
+       <li>
+         A priority-90 flow with the match <code>nd_na</code> and
+         applies the action
+@@ -4452,7 +4458,8 @@ nd_ns {
+           to change the source IP address of a packet from an IP address of
+           <var>A</var> or to change the source IP address of a packet that
+           belongs to network <var>A</var> to <var>B</var>, a flow matches
+-          <code>ip &amp;&amp; ip4.src == <var>A</var></code> with an action
++          <code>ip &amp;&amp; ip4.src == <var>A</var> &amp;&amp;
++          (!ct.trk || !ct.rpl)</code> with an action
+           <code>ct_snat(<var>B</var>);</code>.  The priority of the flow
+           is calculated based on the mask of <var>A</var>, with matches
+           having larger masks getting higher priorities. If the NAT rule is
+diff --git a/rhel/ovn-fedora.spec.in b/rhel/ovn-fedora.spec.in
+index 3fb854a37..821eb03cc 100644
+--- a/rhel/ovn-fedora.spec.in
++++ b/rhel/ovn-fedora.spec.in
+@@ -323,7 +323,7 @@ ln -sf ovn_detrace.py %{_bindir}/ovn-detrace
+ %if %{with libcapng}
+ if [ $1 -eq 1 ]; then
+     sed -i 's:^#OVN_USER_ID=:OVN_USER_ID=:' %{_sysconfdir}/sysconfig/ovn
+-    sed -i 's:\(.*su\).*:\1 ovn ovn:' %{_sysconfdir}/logrotate.d/ovn
++    sed -i 's:\(.*su\).*:\1 openvswitch openvswitch:' %{_sysconfdir}/logrotate.d/ovn
+ fi
+ %endif
+ 
+diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
+index 3865003bf..b7dfcd151 100644
+--- a/tests/ovn-northd.at
++++ b/tests/ovn-northd.at
+@@ -1030,7 +1030,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows | sed 's/table=../table=??/' | sort], [0
+ AT_CHECK([grep -e "lr_out_snat" crflows | sed 's/table=../table=??/' | sort], [0], [dnl
+   table=??(lr_out_snat        ), priority=0    , match=(1), action=(next;)
+   table=??(lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range), action=(ct_snat(172.16.1.1);)
++  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);)
+ ])
+ 
+ 
+@@ -1062,7 +1062,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows2 | sed 's/table=../table=??/' | sort], [
+ AT_CHECK([grep -e "lr_out_snat" crflows2 | sed 's/table=../table=??/' | sort], [0], [dnl
+   table=??(lr_out_snat        ), priority=0    , match=(1), action=(next;)
+   table=??(lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11), action=(ct_snat(172.16.1.1);)
++  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);)
+   table=??(lr_out_snat        ), priority=35   , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;)
+ ])
+ 
+@@ -1091,7 +1091,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows3 | sed 's/table=../table=??/' | sort], [
+ AT_CHECK([grep -e "lr_out_snat" crflows3 | sed 's/table=../table=??/' | sort], [0], [dnl
+   table=??(lr_out_snat        ), priority=0    , match=(1), action=(next;)
+   table=??(lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range), action=(ct_snat(172.16.1.2);)
++  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);)
+ ])
+ 
+ # Stateful FIP with DISALLOWED_IPs
+@@ -1120,7 +1120,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows4 | sed 's/table=../table=??/' | sort], [
+ AT_CHECK([grep -e "lr_out_snat" crflows4 | sed 's/table=../table=??/' | sort], [0], [dnl
+   table=??(lr_out_snat        ), priority=0    , match=(1), action=(next;)
+   table=??(lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11), action=(ct_snat(172.16.1.2);)
++  table=??(lr_out_snat        ), priority=33   , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);)
+   table=??(lr_out_snat        ), priority=35   , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;)
+ ])
+ 
+@@ -3447,7 +3447,7 @@ ls_copp_uuid=$(fetch_column nb:Logical_Switch copp)
+ AT_CHECK([test "$ls_copp_uuid" = "$copp_uuid"])
+ 
+ check ovn-nbctl --wait=hv copp-add $copp_uuid igmp meter0
+-AT_CHECK([ovn-nbctl copp-list copp0], [0], [dnl
++AT_CHECK([ovn-nbctl copp-list copp0 | sort], [0], [dnl
+ arp: meter0
+ igmp: meter0
+ ])
+@@ -5140,11 +5140,12 @@ AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort],
+ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl
+   table=? (lr_out_snat        ), priority=0    , match=(1), action=(next;)
+   table=? (lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);)
++  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);)
+ ])
+ 
++
+ # Set lb force snat logical router.
+ check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="router_ip"
+ check ovn-nbctl --wait=sb sync
+@@ -5201,9 +5202,9 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [
+   table=? (lr_out_snat        ), priority=110  , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);)
+   table=? (lr_out_snat        ), priority=110  , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);)
+   table=? (lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);)
++  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);)
+ ])
+ 
+ # Add a LB VIP same as router ip.
+@@ -5266,9 +5267,9 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [
+   table=? (lr_out_snat        ), priority=110  , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);)
+   table=? (lr_out_snat        ), priority=110  , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);)
+   table=? (lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);)
++  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);)
+ ])
+ 
+ # Add IPv6 router port and LB.
+@@ -5346,9 +5347,9 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [
+   table=? (lr_out_snat        ), priority=110  , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-public"), action=(ct_snat(def0::10);)
+   table=? (lr_out_snat        ), priority=110  , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-sw0"), action=(ct_snat(aef0::1);)
+   table=? (lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
+-  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);)
+-  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);)
++  table=? (lr_out_snat        ), priority=25   , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);)
++  table=? (lr_out_snat        ), priority=33   , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);)
+ ])
+ 
+ check ovn-nbctl lrp-del lr0-sw0
+@@ -5804,6 +5805,12 @@ AT_CHECK([grep lr_in_gw_redirect lrflows | grep cr-DR | sed 's/table=../table=??
+   table=??(lr_in_gw_redirect  ), priority=50   , match=(outport == "DR-S3"), action=(outport = "cr-DR-S3"; next;)
+ ])
+ 
++# Check that ovn-northd logs a warning when trying to configure NAT
++# on the router with multiple distributed gw ports.  Such configurations are
++# not supported yet.
++check ovn-nbctl lr-nat-add DR dnat_and_snat 42.42.42.1 20.0.0.2
++AT_CHECK([grep -q 'NAT is configured on logical router DR, which has 2 distributed gateway ports. NAT is not supported yet when there is more than one distributed gateway port on the router.' northd/ovn-northd.log], [0])
++
+ AT_CLEANUP
+ ])
+ 
+@@ -6426,3 +6433,28 @@ AT_CHECK([grep -e "ls_in_stateful" lsflows | sed 's/table=../table=??/' | sort],
+ 
+ AT_CLEANUP
+ ])
++
++OVN_FOR_EACH_NORTHD([
++AT_SETUP([LR neighbor lookup and learning flows])
++ovn_start
++
++# Create logical routers
++ovn-nbctl --wait=sb lr-add lr0
++
++ovn-sbctl dump-flows lr0 > lrflows
++AT_CAPTURE_FILE([lrflows])
++
++AT_CHECK([cat lrflows | grep -e lr_in_lookup_neighbor -e lr_in_learn_neighbor | sort], [0], [dnl
++  table=1 (lr_in_lookup_neighbor), priority=0    , match=(1), action=(reg9[[2]] = 1; next;)
++  table=1 (lr_in_lookup_neighbor), priority=100  , match=(arp.op == 2), action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); next;)
++  table=1 (lr_in_lookup_neighbor), priority=100  , match=(nd_na), action=(reg9[[2]] = lookup_nd(inport, nd.target, nd.tll); next;)
++  table=1 (lr_in_lookup_neighbor), priority=100  , match=(nd_ns), action=(reg9[[2]] = lookup_nd(inport, ip6.src, nd.sll); next;)
++  table=2 (lr_in_learn_neighbor), priority=100  , match=(reg9[[2]] == 1), action=(next;)
++  table=2 (lr_in_learn_neighbor), priority=90   , match=(arp), action=(put_arp(inport, arp.spa, arp.sha); next;)
++  table=2 (lr_in_learn_neighbor), priority=90   , match=(nd_na), action=(put_nd(inport, nd.target, nd.tll); next;)
++  table=2 (lr_in_learn_neighbor), priority=90   , match=(nd_ns), action=(put_nd(inport, ip6.src, nd.sll); next;)
++  table=2 (lr_in_learn_neighbor), priority=95   , match=(nd_na && nd.tll == 0), action=(put_nd(inport, nd.target, eth.src); next;)
++])
++
++AT_CLEANUP
++])
+diff --git a/tests/ovn.at b/tests/ovn.at
+index 4f65d1ecd..4ee9aebc9 100644
+--- a/tests/ovn.at
++++ b/tests/ovn.at
+@@ -8588,6 +8588,114 @@ OVN_CLEANUP([hv1])
+ AT_CLEANUP
+ ])
+ 
++OVN_FOR_EACH_NORTHD([
++AT_SETUP([send gratuitous arp for l3gateway only on selected chassis])
++ovn_start
++
++# Create logical switch
++ovn-nbctl ls-add ls0
++# Create gateway router
++ovn-nbctl lr-add lr0
++# Add router port to gateway router
++ovn-nbctl lrp-add lr0 lr0-ls0 f0:00:00:00:00:01 192.168.0.1/24
++ovn-nbctl lsp-add ls0 ls0-lr0 -- set Logical_Switch_Port ls0-lr0 \
++    type=router options:router-port=lr0-ls0 addresses='"f0:00:00:00:00:01"'
++
++# Create a localnet port.
++ovn-nbctl lsp-add ls0 ln_port
++ovn-nbctl lsp-set-addresses ln_port unknown
++ovn-nbctl lsp-set-type ln_port localnet
++ovn-nbctl --wait=hv lsp-set-options ln_port network_name=physnet1
++
++# Prepare packets
++touch empty_expected
++echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001" > arp_expected
++
++net_add n1
++sim_add hv1
++as hv1
++ovs-vsctl \
++    -- add-br br-phys \
++    -- add-br br-eth0
++
++ovn_attach n1 br-phys 192.168.0.10
++
++AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
++AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
++
++sim_add hv2
++as hv2
++ovs-vsctl \
++    -- add-br br-phys \
++    -- add-br br-eth0
++
++ovn_attach n1 br-phys 192.168.0.20
++
++AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
++AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv2/snoopvif-tx.pcap options:rxq_pcap=hv2/snoopvif-rx.pcap])
++
++ovn-sbctl dump-flows > sbflows
++AT_CAPTURE_FILE([sbflows])
++
++# Wait until the patch ports are created in hv1 and hv2 to connect br-int to br-eth0
++AT_CHECK([ovn-nbctl set logical_router lr0 options:chassis=hv1])
++OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-vsctl show | \
++grep "Port patch-br-int-to-ln_port" | wc -l`])
++AT_CHECK([ovn-nbctl set logical_router lr0 options:chassis=hv2])
++OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
++grep "Port patch-br-int-to-ln_port" | wc -l`])
++
++# Temporarily remove lr0 chassis
++AT_CHECK([ovn-nbctl remove logical_router lr0 options chassis])
++
++reset_pcap_file() {
++    local hv=$1
++    local iface=$2
++    local pcap_file=$3
++    as $hv
++    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
++options:rxq_pcap=dummy-rx.pcap
++    rm -f ${pcap_file}*.pcap
++    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
++options:rxq_pcap=${pcap_file}-rx.pcap
++}
++
++reset_pcap_file hv1 snoopvif hv1/snoopvif
++reset_pcap_file hv2 snoopvif hv2/snoopvif
++
++hv1_uuid=$(ovn-sbctl --bare --columns _uuid list chassis hv1)
++AT_CHECK([ovn-nbctl set logical_router lr0 options:chassis=hv1])
++OVS_WAIT_UNTIL([
++    ls0_lr0=$(ovn-sbctl --bare --columns chassis list port_binding ls0-lr0)
++    test "$ls0_lr0" = $hv1_uuid
++])
++
++sleep 2
++OVN_CHECK_PACKETS_CONTAIN([hv1/snoopvif-tx.pcap], [arp_expected])
++OVN_CHECK_PACKETS([hv2/snoopvif-tx.pcap], [empty_expected])
++
++# Temporarily remove lr0 chassis
++AT_CHECK([ovn-nbctl remove logical_router lr0 options chassis])
++
++reset_pcap_file hv1 snoopvif hv1/snoopvif
++reset_pcap_file hv2 snoopvif hv2/snoopvif
++
++hv2_uuid=$(ovn-sbctl --bare --columns _uuid list chassis hv2)
++AT_CHECK([ovn-nbctl set logical_router lr0 options:chassis=hv2])
++OVS_WAIT_UNTIL([
++    ls0_lr0=$(ovn-sbctl --bare --columns chassis list port_binding ls0-lr0)
++    test "$ls0_lr0" = $hv2_uuid
++])
++
++sleep 2
++OVN_CHECK_PACKETS_CONTAIN([hv2/snoopvif-tx.pcap], [arp_expected])
++OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [empty_expected])
++
++OVN_CLEANUP([hv1],[hv2])
++
++AT_CLEANUP
++])
++
+ OVN_FOR_EACH_NORTHD([
+ AT_SETUP([send gratuitous arp with nat-addresses router in localnet])
+ ovn_start
+@@ -9403,6 +9511,10 @@ check ovn-nbctl --wait=hv qos-add lsw0 to-lport 1002 'inport=="lp2" && is_chassi
+ AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep meter | wc -l], [0], [4
+ ])
+ 
++check ovn-nbctl qos-del lsw0
++AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
++])
++
+ OVN_CLEANUP([hv])
+ AT_CLEANUP
+ ])
+@@ -13988,6 +14100,99 @@ OVN_CLEANUP([hv1],[hv2])
+ AT_CLEANUP
+ ])
+ 
++OVN_FOR_EACH_NORTHD([
++AT_SETUP([garps disabled when port no longer bound to chassis])
++ovn_start
++
++net_add n1
++for i in 1 2; do
++    sim_add hv$i
++    as hv$i
++    check ovs-vsctl add-br br-phys
++    ovn_attach n1 br-phys 192.168.0.$i
++    check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
++done
++
++check ovn-nbctl ls-add ls0
++check ovn-nbctl lsp-add ls0 port
++check ovn-nbctl lsp-set-addresses port "00:00:00:00:00:01 10.0.0.1"
++
++check ovn-nbctl lsp-add ls0 public
++check ovn-nbctl lsp-set-addresses public unknown
++check ovn-nbctl lsp-set-type public localnet
++check ovn-nbctl lsp-set-options public network_name=phys
++
++for hv in hv1 hv2; do
++    as $hv check ovs-vsctl -- add-port br-int port -- \
++        set Interface port external-ids:iface-id=port \
++        options:tx_pcap=$hv/port-tx.pcap \
++        options:rxq_pcap=$hv/port-rx.pcap
++done
++
++reset_pcap_file() {
++    local hv=$1
++    local iface=$2
++    local pcap_file=$3
++    as $hv check ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
++                                                   options:rxq_pcap=dummy-rx.pcap
++    check rm -f ${pcap_file}*.pcap
++    as $hv check ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
++                                                   options:rxq_pcap=${pcap_file}-rx.pcap
++}
++
++reset_env() {
++    reset_pcap_file hv1 br-phys_n1 hv1/br-phys_n1
++    reset_pcap_file hv2 br-phys_n1 hv2/br-phys_n1
++
++    for port in hv1/n1 hv2/n1; do
++        : > $port.expected
++    done
++}
++
++for hv in hv1 hv2; do
++    wait_row_count Chassis 1 name=$hv
++done
++hv1_uuid=$(fetch_column Chassis _uuid name=hv1)
++hv2_uuid=$(fetch_column Chassis _uuid name=hv2)
++
++OVN_POPULATE_ARP
++
++# Activate port on each hv giving a chance to each chassis to enable garps
++check ovn-nbctl lsp-set-options port requested-chassis=hv1
++wait_column "$hv1_uuid" Port_Binding chassis logical_port=port
++wait_column "$hv1_uuid" Port_Binding requested_chassis logical_port=port
++wait_for_ports_up
++reset_env
++
++# give chassis some time to generate garps
++sleep 2
++
++expected_garp=ffffffffffff000000000001080600010800060400010000000000010a0000010000000000000a000001
++
++# check hv1 sends garps and hv2 doesn't
++echo $expected_garp >> hv1/n1.expected
++OVN_CHECK_PACKETS_CONTAIN([hv1/br-phys_n1-tx.pcap], [hv1/n1.expected])
++OVN_CHECK_PACKETS([hv2/br-phys_n1-tx.pcap], [hv2/n1.expected])
++
++check ovn-nbctl lsp-set-options port requested-chassis=hv2
++wait_column "$hv2_uuid" Port_Binding chassis logical_port=port
++wait_column "$hv2_uuid" Port_Binding requested_chassis logical_port=port
++wait_for_ports_up
++reset_env
++
++# give chassis some time to generate garps
++sleep 2
++
++# check hv2 sends garps and hv1 doesn't
++echo $expected_garp >> hv2/n1.expected
++OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [hv1/n1.expected])
++OVN_CHECK_PACKETS_CONTAIN([hv2/br-phys_n1-tx.pcap], [hv2/n1.expected])
++
++OVN_CLEANUP([hv1],[hv2])
++
++AT_CLEANUP
++])
++
+ OVN_FOR_EACH_NORTHD([
+ AT_SETUP([IPv6 periodic RA disabled for localnet adjacent switch ports])
+ ovn_start
+@@ -15243,6 +15448,92 @@ OVN_CLEANUP([hv1])
+ AT_CLEANUP
+ ])
+ 
++# This test ensures that the incremental flow installation works well when
++# handling update->delete->add/update for the same OVS flow.
++OVN_FOR_EACH_NORTHD([
++AT_SETUP([ACL conjunction append and reprocess])
++ovn_start
++
++net_add n1
++sim_add hv1
++as hv1
++check ovs-vsctl add-br br-phys
++ovn_attach n1 br-phys 192.168.0.1
++
++# Setup the desired state:
++# - Two ACLs, each matches its own port-group (pg1 & pg2), and matches the same
++#   set of IP addresses.
++# - pg1 includes p1, p2, p3
++# - pg2 includes p4, p5
++check ovn-nbctl ls-add sw
++check ovn-nbctl lsp-add sw p1 -- lsp-set-addresses p1 "00:00:00:00:00:02 192.168.0.2"
++check ovn-nbctl lsp-add sw p2 -- lsp-set-addresses p2 "00:00:00:00:00:03 192.168.0.3"
++check ovn-nbctl lsp-add sw p3 -- lsp-set-addresses p3 "00:00:00:00:00:04 192.168.0.4"
++check ovn-nbctl lsp-add sw p4 -- lsp-set-addresses p4 "00:00:00:00:00:05 192.168.0.5"
++check ovn-nbctl lsp-add sw p5 -- lsp-set-addresses p5 "00:00:00:00:00:06 192.168.0.6"
++check ovn-nbctl pg-add pg1 p1 p2 p3
++check ovn-nbctl pg-add pg2 p4 p5
++check ovs-vsctl add-port br-int p1 -- set Interface p1 external_ids:iface-id=p1
++check ovs-vsctl add-port br-int p2 -- set Interface p2 external_ids:iface-id=p2
++check ovs-vsctl add-port br-int p3 -- set Interface p3 external_ids:iface-id=p3
++check ovs-vsctl add-port br-int p4 -- set Interface p4 external_ids:iface-id=p4
++check ovs-vsctl add-port br-int p5 -- set Interface p5 external_ids:iface-id=p5
++check ovn-nbctl acl-add pg1 to-lport 1000 "outport==@pg1 && ip4 && ip4.src == {10.0.0.1, 10.0.0.2}" allow
++check ovn-nbctl acl-add pg2 to-lport 1000 "outport==@pg2 && ip4 && ip4.src == {10.0.0.1, 10.0.0.2}" allow
++check ovn-nbctl --wait=hv sync
++
++# Now we should have two flows with combined conjunctions.
++OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
++grep conjunction.*conjunction | wc -l`])
++
++
++# Test the scenario 10 times to give enough chance to hit the
++# "update->delete->add/update" scenario, because we can't decide the order of
++# change handling inside ovn-controller.
++for i in $(seq 10); do
++# Unbind the p3 and p5, the combined conjunctions should be gone.
++ovs-vsctl del-port br-int p3
++ovs-vsctl del-port br-int p5
++OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int | \
++grep conjunction.*conjunction | wc -l`])
++
++# Delete and re-add the ACLs, just to bring some randomness in the lflow
++# processing order, so that there is a chance that the order of adding and
++# appending are the same before & after the flow deletion, so that the
++# generated combined conjunctions are the same before & after the flow
++# deletion. (If the order is different, the combined conjunctions order is
++# different and the action comparison would fail, so won't trigger the tracked
++# flow merging. We want to make sure that we test the merging scenario)
++ovn-nbctl acl-del pg1 to-lport 1000 "outport==@pg1 && ip4 && ip4.src == {10.0.0.1, 10.0.0.2}"
++ovn-nbctl acl-del pg2 to-lport 1000 "outport==@pg2 && ip4 && ip4.src == {10.0.0.1, 10.0.0.2}"
++ovn-nbctl acl-add pg1 to-lport 1000 "outport==@pg1 && ip4 && ip4.src == {10.0.0.1, 10.0.0.2}" allow
++ovn-nbctl acl-add pg2 to-lport 1000 "outport==@pg2 && ip4 && ip4.src == {10.0.0.1, 10.0.0.2}" allow
++ovn-nbctl --wait=hv sync
++
++# Now re-bind p3 and p5 in the same transaction, so that pg1 and pg2 update are
++# handled in the same I-P engine run. The order of pg1 and pg2 can be random.
++# If the order is pg2 -> pg1, then it should trigger the OVS flow
++# "update->delete->add/update" scenario:
++# 1) when pg2 update is handled, the ACL-2 would append conjunctions to
++#    the conjunction flows of ACL-1
++# 2) when pg1 update is handled, it would flood remove flows of both ACL-1 and
++#    ACL-2, including the "appended" conjunction flows. And then reprocess
++#    ACL-1 and ACL-2 would re-add and re-append the conjunction flows with
++#    combined conjunctions.
++ovs-vsctl add-port br-int p3 -- set Interface p3 external_ids:iface-id=p3 -- \
++    add-port br-int p5 -- set Interface p5 external_ids:iface-id=p5
++ovn-nbctl --wait=hv sync
++
++# Now making sure we end up with two combined conjunctions.
++OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
++grep conjunction.*conjunction | wc -l`])
++
++done
++
++OVN_CLEANUP([hv1])
++AT_CLEANUP
++])
++
+ OVN_FOR_EACH_NORTHD([
+ AT_SETUP([Superseding ACLs with conjunction])
+ ovn_start
+diff --git a/tests/system-ovn.at b/tests/system-ovn.at
+index c4a2c39f6..018dcea2a 100644
+--- a/tests/system-ovn.at
++++ b/tests/system-ovn.at
+@@ -6922,10 +6922,10 @@ p = IP(src="192.168.1.2", dst="192.168.1.1") / UDP(dport = 12345) / Raw(b"X"*64)
+ send (p, iface='sw01', loop = 0, verbose = 0, count = 20)
+ EOF
+ 
+-# 1pps + 1 burst size
++# 1pps
+ OVS_WAIT_UNTIL([
+     n_reject=$(grep unreachable reject.pcap | wc -l)
+-    test "${n_reject}" = "2"
++    test "${n_reject}" = "1"
+ ])
+ kill $(pidof tcpdump)
+ rm -f reject.pcap
+@@ -6938,10 +6938,10 @@ p = IP(src="192.168.1.2", dst="192.168.1.1") / UDP(dport = 12345) / Raw(b"X"*64)
+ send (p, iface='sw01', loop = 0, verbose = 0, count = 100)
+ EOF
+ 
+-# 10pps + 1 burst size
++# 10pps
+ OVS_WAIT_UNTIL([
+     n_reject=$(grep unreachable reject.pcap | wc -l)
+-    test "${n_reject}" = "20"
++    test "${n_reject}" = "10"
+ ])
+ 
+ kill $(pidof tcpdump)
+@@ -6974,10 +6974,10 @@ p = IP(src="192.168.1.2", dst="172.16.1.100") / TCP(dport = 80, flags="S") / Raw
+ send (p, iface='sw01', loop = 0, verbose = 0, count = 100)
+ EOF
+ 
+-# 1pps + 1 burst size
++# 1pps
+ OVS_WAIT_UNTIL([
+     n_arp=$(grep ARP arp.pcap | wc -l)
+-    test "${n_arp}" = "2"
++    test "${n_arp}" = "1"
+ ])
+ kill $(pidof tcpdump)
+ 
+@@ -6994,10 +6994,10 @@ p = IP(src="192.168.1.2", dst="172.16.1.100", ttl=1) / TCP(dport = 8080, flags="
+ send (p, iface='sw01', loop = 0, verbose = 0, count = 100)
+ EOF
+ 
+-# 1pps + 1 burst size
++# 1pps
+ OVS_WAIT_UNTIL([
+     n_icmp=$(grep ICMP icmp.pcap | wc -l)
+-    test "${n_icmp}" = "2"
++    test "${n_icmp}" = "1"
+ ])
+ kill $(pidof tcpdump)
+ 
+@@ -7010,7 +7010,7 @@ bfd: bfd-meter
+ 
+ check ovn-nbctl --bfd lr-route-add R1 240.0.0.0/8 172.16.1.50 rp-public
+ printf "%08x" $(ovn-sbctl get bfd . disc) > /tmp/disc
+-NS_EXEC([server], [tcpdump -l -n -i s1 udp port 3784 -Q in > bfd.pcap &])
++NS_EXEC([server], [tcpdump -l -nn -i s1 udp port 3784 and ip[[29]]==0x90 -Q in > bfd.pcap &])
+ ip netns exec server scapy -H <<-EOF
+ import binascii
+ f = open("/tmp/disc", "r")
+@@ -7023,10 +7023,10 @@ f.close()
+ EOF
+ rm /tmp/disc
+ 
+-# 1pps + 1 burst size
++# 1pps
+ OVS_WAIT_UNTIL([
+-    n_tcp_rst=$(grep Final bfd.pcap | wc -l)
+-    test "${n_tcp_rst}" = "2"
++    n_bfd=$(grep 3784 bfd.pcap | wc -l)
++    test "${n_bfd}" = "1"
+ ])
+ kill $(pidof tcpdump)
+ 
+@@ -7992,3 +7992,122 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
+ 
+ AT_CLEANUP
+ ])
++
++OVN_FOR_EACH_NORTHD([
++AT_SETUP([East-West traffic with gateway router if DNAT configured])
++AT_KEYWORDS([ovnnat])
++
++CHECK_CONNTRACK()
++CHECK_CONNTRACK_NAT()
++ovn_start
++OVS_TRAFFIC_VSWITCHD_START()
++ADD_BR([br-int])
++# Set external-ids in br-int needed for ovn-controller
++ovs-vsctl \
++        -- set Open_vSwitch . external-ids:system-id=hv1 \
++        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
++        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
++        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
++        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
++
++# Start ovn-controller
++start_daemon ovn-controller
++# Logical network:
++# One LR - R1  has two switches: sw0 and sw1
++#    sw0 -- R1 -- sw1
++# Logical port 'sw01' in switch 'sw0'.
++# Logical port 'sw11' in switch 'sw1'.
++# nc server running in sw01
++# nc client running on sw11
++
++check ovn-nbctl lr-add R1
++check ovn-nbctl ls-add sw0
++check ovn-nbctl ls-add sw1
++
++check ovn-nbctl lrp-add R1 rp-sw0 00:00:01:01:02:03 192.168.1.1/24
++check ovn-nbctl lrp-add R1 rp-sw1 00:00:03:01:02:03 192.168.2.1/24
++check ovn-nbctl set logical_router R1 options:chassis=hv1
++
++check ovn-nbctl lsp-add sw0 sw0-rp -- set Logical_Switch_Port sw0-rp \
++    type=router options:router-port=rp-sw0 \
++    -- lsp-set-addresses sw0-rp router
++check ovn-nbctl lsp-add sw1 sw1-rp -- set Logical_Switch_Port sw1-rp \
++    type=router options:router-port=rp-sw1 \
++    -- lsp-set-addresses sw1-rp router
++
++ADD_NAMESPACES(sw01)
++ADD_VETH(sw01, sw01, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
++       "192.168.1.1")
++check ovn-nbctl lsp-add sw0 sw01 \
++    -- lsp-set-addresses sw01 "f0:00:00:01:02:03 192.168.1.2"
++
++ADD_NAMESPACES(sw11)
++ADD_VETH(sw11, sw11, br-int, "192.168.2.2/24", "f0:00:00:02:02:03", \
++       "192.168.2.1")
++check ovn-nbctl lsp-add sw1 sw11 \
++    -- lsp-set-addresses sw11 "f0:00:00:02:02:03 192.168.2.2"
++
++NETNS_DAEMONIZE([sw01], [nc -k -l 8000], [nc-sw01.pid])
++
++test_ping() {
++    NS_CHECK_EXEC([$1],  [ping -q -c 1 $2 -w 2 | FORMAT_PING], \
++[0], [dnl
++1 packets transmitted, 1 received, 0% packet loss, time 0ms
++])
++}
++
++# Only SNAT
++check ovn-nbctl --wait=hv lr-nat-add R1 snat 172.16.1.21 192.168.2.0/24
++
++echo "foo" > foo
++NS_CHECK_EXEC([sw11], [nc 192.168.1.2 8000 < foo])
++test_ping sw11 192.168.1.2
++
++# Ensure nat has been hit
++OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep -v "n_packets=0" | grep 'nat(src=172.16.1.21)'])
++# Ensure conntrack entry is present
++OVS_WAIT_FOR_OUTPUT([
++    ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \
++      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
++icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared>
++tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
++])
++
++AT_CHECK([ovs-appctl dpctl/flush-conntrack])
++
++# SNAT and DNAT. using Logical IP
++ovn-nbctl --wait=hv lr-nat-add R1 dnat_and_snat 172.16.1.2 192.168.1.2
++NS_CHECK_EXEC([sw11], [nc 192.168.1.2 8000 < foo ])
++test_ping sw11 192.168.1.2
++
++# Ensure conntrack entry is present
++OVS_WAIT_FOR_OUTPUT([
++    ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \
++      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
++icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared>
++tcp,orig=(src=192.168.2.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
++])
++
++AT_CHECK([ovs-appctl dpctl/flush-conntrack])
++
++# SNAT and DNAT. using floating IP
++NS_CHECK_EXEC([sw11], [nc 172.16.1.2 8000 < foo ])
++test_ping sw11 172.16.1.2
++
++# Ensure conntrack entry is present
++OVS_WAIT_FOR_OUTPUT([
++    ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \
++      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
++icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared>
++tcp,orig=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
++])
++
++AT_CHECK([ovs-appctl dpctl/flush-conntrack])
++
++OVS_APP_EXIT_AND_WAIT([ovn-controller])
++as
++OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
++/connection dropped.*/d"])
++
++AT_CLEANUP
++])
+diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c
+index 7bcc2c66a..7fcfa50d4 100644
+--- a/utilities/ovn-nbctl.c
++++ b/utilities/ovn-nbctl.c
+@@ -2856,7 +2856,7 @@ nbctl_lb_add(struct ctl_context *ctx)
+     }
+ 
+     struct sockaddr_storage ss_vip;
+-    if (!inet_parse_active(lb_vip, 0, &ss_vip, false)) {
++    if (!inet_parse_active(lb_vip, 0, &ss_vip, false, NULL)) {
+         ctl_error(ctx, "%s: should be an IP address (or an IP address "
+                   "and a port number with : as a separator).", lb_vip);
+         return;
+@@ -2886,7 +2886,7 @@ nbctl_lb_add(struct ctl_context *ctx)
+         struct sockaddr_storage ss_dst;
+ 
+         if (lb_vip_port) {
+-            if (!inet_parse_active(token, -1, &ss_dst, false)) {
++            if (!inet_parse_active(token, -1, &ss_dst, false, NULL)) {
+                 ctl_error(ctx, "%s: should be an IP address and a port "
+                           "number with : as a separator.", token);
+                 goto out;
+@@ -3032,7 +3032,7 @@ lb_info_add_smap(const struct nbrec_load_balancer *lb,
+             const struct smap_node *node = nodes[i];
+ 
+             struct sockaddr_storage ss;
+-            if (!inet_parse_active(node->key, 0, &ss, false)) {
++            if (!inet_parse_active(node->key, 0, &ss, false, NULL)) {
+                 continue;
+             }
+ 
+diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c
+index ece5803f2..096d691d5 100644
+--- a/utilities/ovn-trace.c
++++ b/utilities/ovn-trace.c
+@@ -214,7 +214,7 @@ static void
+ parse_lb_option(const char *s)
+ {
+     struct sockaddr_storage ss;
+-    if (!inet_parse_active(s, 0, &ss, false)) {
++    if (!inet_parse_active(s, 0, &ss, false, NULL)) {
+         ovs_fatal(0, "%s: bad address", s);
+     }
+ 
+@@ -1388,7 +1388,8 @@ ovntrace_node_prune_summary(struct ovs_list *nodes)
+             sub->type == OVNTRACE_NODE_TABLE) {
+             /* Replace 'sub' by its children, if any, */
+             ovs_list_remove(&sub->node);
+-            ovs_list_splice(&next->node, sub->subs.next, &sub->subs);
++            ovs_list_splice(next ? &next->node : nodes, sub->subs.next,
++                            &sub->subs);
+             ovntrace_node_destroy(sub);
+         }
+     }
+@@ -1432,7 +1433,8 @@ ovntrace_node_prune_hard(struct ovs_list *nodes)
+             sub->type == OVNTRACE_NODE_OUTPUT) {
+             /* Replace 'sub' by its children, if any, */
+             ovs_list_remove(&sub->node);
+-            ovs_list_splice(&next->node, sub->subs.next, &sub->subs);
++            ovs_list_splice(next ? &next->node : nodes, sub->subs.next,
++                            &sub->subs);
+             ovntrace_node_destroy(sub);
+         }
+     }
diff --git a/SOURCES/ppc_64-power8-linuxapp-gcc-config b/SOURCES/ppc_64-power8-linuxapp-gcc-config
new file mode 100644
index 0000000..2319b68
--- /dev/null
+++ b/SOURCES/ppc_64-power8-linuxapp-gcc-config
@@ -0,0 +1,550 @@
+# -*- cfg-sha: ac783e64ca20c977a7c1c42e72e6dce151b31aa9aecfbfa121b45e49e938f418
+# BSD LICENSE
+# Copyright (C) IBM Corporation 2014.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of IBM Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2016 Intel Corporation
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2017 Intel Corporation
+# RTE_EXEC_ENV values are the directories in mk/exec-env/
+CONFIG_RTE_EXEC_ENV="linuxapp"
+# RTE_ARCH values are architecture we compile for. directories in mk/arch/
+CONFIG_RTE_ARCH="ppc_64"
+# machine can define specific variables or action for a specific board
+# RTE_MACHINE values are architecture we compile for. directories in mk/machine/
+CONFIG_RTE_MACHINE="power8"
+# The compiler we use.
+# RTE_TOOLCHAIN values are architecture we compile for. directories in mk/toolchain/
+CONFIG_RTE_TOOLCHAIN="gcc"
+# Use intrinsics or assembly code for key routines
+CONFIG_RTE_FORCE_INTRINSICS=n
+# Machine forces strict alignment constraints.
+CONFIG_RTE_ARCH_STRICT_ALIGN=n
+# Compile to share library
+CONFIG_RTE_BUILD_SHARED_LIB=n
+# Use newest code breaking previous ABI
+CONFIG_RTE_NEXT_ABI=n
+# Major ABI to overwrite library specific LIBABIVER
+CONFIG_RTE_MAJOR_ABI=
+# Machine's cache line size
+CONFIG_RTE_CACHE_LINE_SIZE=128
+# Memory model
+CONFIG_RTE_USE_C11_MEM_MODEL=n
+# Compile Environment Abstraction Layer
+CONFIG_RTE_LIBRTE_EAL=y
+CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_MAX_NUMA_NODES=32
+CONFIG_RTE_MAX_HEAPS=32
+CONFIG_RTE_MAX_MEMSEG_LISTS=64
+# each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
+# or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
+CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
+CONFIG_RTE_MAX_MEM_MB_PER_LIST=32768
+# a "type" is a combination of page size and NUMA node. total number of memseg
+# lists per type will be limited to either RTE_MAX_MEMSEG_PER_TYPE pages (split
+# over multiple lists of RTE_MAX_MEMSEG_PER_LIST pages), or
+# RTE_MAX_MEM_MB_PER_TYPE megabytes of memory (split over multiple lists of
+# RTE_MAX_MEM_MB_PER_LIST), whichever is smaller
+CONFIG_RTE_MAX_MEMSEG_PER_TYPE=32768
+CONFIG_RTE_MAX_MEM_MB_PER_TYPE=131072
+# global maximum usable amount of VA, in megabytes
+CONFIG_RTE_MAX_MEM_MB=524288
+CONFIG_RTE_MAX_MEMZONE=2560
+CONFIG_RTE_MAX_TAILQ=32
+CONFIG_RTE_ENABLE_ASSERT=n
+CONFIG_RTE_LOG_DP_LEVEL=RTE_LOG_INFO
+CONFIG_RTE_LOG_HISTORY=256
+CONFIG_RTE_BACKTRACE=y
+CONFIG_RTE_LIBEAL_USE_HPET=n
+CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
+CONFIG_RTE_EAL_IGB_UIO=n
+CONFIG_RTE_EAL_VFIO=y
+CONFIG_RTE_MAX_VFIO_GROUPS=64
+CONFIG_RTE_MAX_VFIO_CONTAINERS=64
+CONFIG_RTE_MALLOC_DEBUG=n
+CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=y
+CONFIG_RTE_USE_LIBBSD=n
+# Recognize/ignore architecture we compile for. AVX/AVX512 CPU flags for performance/power testing.
+# AVX512 is marked as experimental for now, will enable it after enough
+# field test and possible optimization.
+CONFIG_RTE_ENABLE_AVX=y
+CONFIG_RTE_ENABLE_AVX512=n
+# Default driver path (or "" to disable)
+CONFIG_RTE_EAL_PMD_PATH=""
+# Compile Environment Abstraction Layer to support Vmware TSC map
+CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=n
+# Compile architecture we compile for. PCI library
+CONFIG_RTE_LIBRTE_PCI=y
+# Compile architecture we compile for. argument parser library
+CONFIG_RTE_LIBRTE_KVARGS=y
+# Compile generic ethernet library
+CONFIG_RTE_LIBRTE_ETHER=y
+CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
+CONFIG_RTE_MAX_ETHPORTS=32
+CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
+CONFIG_RTE_LIBRTE_IEEE1588=n
+CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
+CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
+CONFIG_RTE_ETHDEV_PROFILE_WITH_VTUNE=n
+# Turn off Tx preparation stage
+# Warning: rte_eth_tx_prepare() can be safely disabled only if using a
+# driver which do not implement any Tx preparation.
+CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
+# Common libraries, before Bus/PMDs
+CONFIG_RTE_LIBRTE_COMMON_DPAAX=n
+# Compile architecture we compile for. Intel FPGA bus
+CONFIG_RTE_LIBRTE_IFPGA_BUS=n
+# Compile PCI bus driver
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+# Compile architecture we compile for. vdev bus
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
+# Compile ARK PMD
+CONFIG_RTE_LIBRTE_ARK_PMD=n
+CONFIG_RTE_LIBRTE_ARK_PAD_TX=y
+CONFIG_RTE_LIBRTE_ARK_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_STATS=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_TRACE=n
+# Compile Aquantia Atlantic PMD driver
+CONFIG_RTE_LIBRTE_ATLANTIC_PMD=n
+# Compile AMD PMD
+CONFIG_RTE_LIBRTE_AXGBE_PMD=n
+CONFIG_RTE_LIBRTE_AXGBE_PMD_DEBUG=n
+# Compile burst-oriented Broadcom PMD driver
+CONFIG_RTE_LIBRTE_BNX2X_PMD=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
+# Compile burst-oriented Broadcom BNXT PMD driver
+CONFIG_RTE_LIBRTE_BNXT_PMD=n
+# Compile burst-oriented Chelsio Terminator (CXGBE) PMD
+CONFIG_RTE_LIBRTE_CXGBE_PMD=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_CXGBE_TPUT=y
+# NXP DPAA Bus
+CONFIG_RTE_LIBRTE_DPAA_BUS=n
+CONFIG_RTE_LIBRTE_DPAA_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA_PMD=n
+CONFIG_RTE_LIBRTE_DPAA_HWDEBUG=n
+# Compile NXP DPAA2 FSL-MC Bus
+CONFIG_RTE_LIBRTE_FSLMC_BUS=n
+# Compile Support Libraries for NXP DPAA2
+CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
+# Compile burst-oriented NXP DPAA2 PMD driver
+CONFIG_RTE_LIBRTE_DPAA2_PMD=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
+# Compile NXP ENETC PMD Driver
+CONFIG_RTE_LIBRTE_ENETC_PMD=n
+# Compile burst-oriented Amazon ENA PMD driver
+CONFIG_RTE_LIBRTE_ENA_PMD=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_ENA_COM_DEBUG=n
+# Compile burst-oriented Cisco ENIC PMD driver
+CONFIG_RTE_LIBRTE_ENIC_PMD=n
+# Compile burst-oriented IGB & EM PMD drivers
+CONFIG_RTE_LIBRTE_EM_PMD=n
+CONFIG_RTE_LIBRTE_IGB_PMD=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
+# Compile burst-oriented IXGBE PMD driver
+CONFIG_RTE_LIBRTE_IXGBE_PMD=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
+CONFIG_RTE_IXGBE_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_IXGBE_BYPASS=n
+# Compile burst-oriented I40E PMD driver
+CONFIG_RTE_LIBRTE_I40E_PMD=y
+CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
+CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
+# Compile burst-oriented FM10K PMD
+CONFIG_RTE_LIBRTE_FM10K_PMD=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
+CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
+# Compile burst-oriented AVF PMD driver
+CONFIG_RTE_LIBRTE_AVF_PMD=n
+CONFIG_RTE_LIBRTE_AVF_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_AVF_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_AVF_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_AVF_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_AVF_16BYTE_RX_DESC=n
+# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
+CONFIG_RTE_LIBRTE_MLX4_PMD=n
+CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS=n
+# Compile burst-oriented Mellanox ConnectX-4, ConnectX-5 & Bluefield
+# (MLX5) PMD
+CONFIG_RTE_LIBRTE_MLX5_PMD=n
+CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS=n
+# Compile burst-oriented Netronome NFP PMD driver
+CONFIG_RTE_LIBRTE_NFP_PMD=n
+CONFIG_RTE_LIBRTE_NFP_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_NFP_DEBUG_RX=n
+# QLogic 10G/25G/40G/50G/100G PMD
+CONFIG_RTE_LIBRTE_QEDE_PMD=n
+CONFIG_RTE_LIBRTE_QEDE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_QEDE_DEBUG_RX=n
+#Provides abs path/name of architecture we compile for. firmware file.
+#Empty string denotes driver will use default firmware
+CONFIG_RTE_LIBRTE_QEDE_FW=""
+# Compile burst-oriented Solarflare libefx-based PMD
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
+CONFIG_RTE_LIBRTE_SFC_EFX_DEBUG=n
+# Compile software PMD backed by SZEDATA2 device
+CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
+# Compile burst-oriented Cavium Thunderx NICVF PMD driver
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD=n
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX=n
+# Compile burst-oriented Cavium LiquidIO PMD driver
+CONFIG_RTE_LIBRTE_LIO_PMD=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_REGS=n
+# Compile burst-oriented Cavium OCTEONTX network PMD driver
+CONFIG_RTE_LIBRTE_OCTEONTX_PMD=n
+# Compile WRS accelerated virtual port (AVP) guest PMD driver
+CONFIG_RTE_LIBRTE_AVP_PMD=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_BUFFERS=n
+# Compile burst-oriented VIRTIO PMD driver
+CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
+# Compile virtio device emulation inside virtio PMD driver
+CONFIG_RTE_VIRTIO_USER=n
+# Compile burst-oriented VMXNET3 PMD driver
+CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
+# Compile software PMD backed by AF_PACKET sockets (Linux only)
+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
+# Compile link bonding PMD library
+CONFIG_RTE_LIBRTE_PMD_BOND=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
+# Compile fail-safe PMD
+CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y
+# Compile Marvell PMD driver
+CONFIG_RTE_LIBRTE_MVPP2_PMD=n
+# Compile Marvell MVNETA PMD driver
+CONFIG_RTE_LIBRTE_MVNETA_PMD=n
+# Compile support for VMBus library
+CONFIG_RTE_LIBRTE_VMBUS=n
+# Compile native PMD for Hyper-V/Azure
+CONFIG_RTE_LIBRTE_NETVSC_PMD=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_DUMP=n
+# Compile virtual device driver for NetVSC on Hyper-V/Azure
+CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD=n
+# Compile null PMD
+CONFIG_RTE_LIBRTE_PMD_NULL=n
+# Compile software PMD backed by PCAP files
+CONFIG_RTE_LIBRTE_PMD_PCAP=n
+# Compile example software rings based PMD
+CONFIG_RTE_LIBRTE_PMD_RING=y
+CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
+CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
+# Compile SOFTNIC PMD
+CONFIG_RTE_LIBRTE_PMD_SOFTNIC=n
+# Compile architecture we compile for. TAP PMD
+# It is enabled by default for Linux only.
+CONFIG_RTE_LIBRTE_PMD_TAP=y
+# Do prefetch of packet data within PMD driver receive function
+CONFIG_RTE_PMD_PACKET_PREFETCH=y
+# Compile generic wireless base band device library
+# EXPERIMENTAL: API may change without prior notice
+CONFIG_RTE_LIBRTE_BBDEV=n
+CONFIG_RTE_BBDEV_MAX_DEVS=128
+CONFIG_RTE_BBDEV_OFFLOAD_COST=n
+# Compile PMD for NULL bbdev device
+CONFIG_RTE_LIBRTE_PMD_BBDEV_NULL=y
+# Compile PMD for turbo software bbdev device
+CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW=n
+# Compile generic crypto device library
+CONFIG_RTE_LIBRTE_CRYPTODEV=n
+CONFIG_RTE_CRYPTO_MAX_DEVS=64
+# Compile PMD for ARMv8 Crypto device
+CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO=n
+CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO_DEBUG=n
+# Compile NXP CAAM JR crypto Driver
+CONFIG_RTE_LIBRTE_PMD_CAAM_JR=n
+CONFIG_RTE_LIBRTE_PMD_CAAM_JR_BE=n
+# Compile NXP DPAA2 crypto sec driver for CAAM HW
+CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=n
+# NXP DPAA caam - crypto driver
+CONFIG_RTE_LIBRTE_PMD_DPAA_SEC=n
+CONFIG_RTE_LIBRTE_DPAA_MAX_CRYPTODEV=4
+# Compile PMD for Cavium OCTEON TX crypto device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_CRYPTO=y
+# Compile PMD for QuickAssist based devices - see docs for details
+CONFIG_RTE_LIBRTE_PMD_QAT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_SYM=n
+# Max. number of QuickAssist devices, which can be detected and attached
+CONFIG_RTE_PMD_QAT_MAX_PCI_DEVICES=48
+CONFIG_RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS=16
+CONFIG_RTE_PMD_QAT_COMP_IM_BUFFER_SIZE=65536
+# Compile PMD for virtio crypto devices
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO=n
+# Number of maximum virtio crypto devices
+CONFIG_RTE_MAX_VIRTIO_CRYPTO=32
+# Compile PMD for AESNI backed device
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
+# Compile PMD for Software backed device
+CONFIG_RTE_LIBRTE_PMD_OPENSSL=n
+# Compile PMD for AESNI GCM device
+CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n
+# Compile PMD for SNOW 3G device
+CONFIG_RTE_LIBRTE_PMD_SNOW3G=n
+CONFIG_RTE_LIBRTE_PMD_SNOW3G_DEBUG=n
+# Compile PMD for KASUMI device
+CONFIG_RTE_LIBRTE_PMD_KASUMI=n
+# Compile PMD for ZUC device
+CONFIG_RTE_LIBRTE_PMD_ZUC=n
+# Compile PMD for Crypto Scheduler device
+CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER=n
+# Compile PMD for NULL Crypto device
+CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO=n
+# Compile PMD for AMD CCP crypto device
+CONFIG_RTE_LIBRTE_PMD_CCP=n
+# Compile PMD for Marvell Crypto device
+CONFIG_RTE_LIBRTE_PMD_MVSAM_CRYPTO=n
+# Compile generic security library
+CONFIG_RTE_LIBRTE_SECURITY=n
+# Compile generic compression device library
+CONFIG_RTE_LIBRTE_COMPRESSDEV=n
+CONFIG_RTE_COMPRESS_MAX_DEVS=64
+# Compile compressdev unit test
+CONFIG_RTE_COMPRESSDEV_TEST=n
+# Compile PMD for Octeontx ZIPVF compression device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_ZIPVF=n
+# Compile PMD for ISA-L compression device
+CONFIG_RTE_LIBRTE_PMD_ISAL=n
+# Compile PMD for ZLIB compression device
+CONFIG_RTE_LIBRTE_PMD_ZLIB=n
+# Compile generic event device library
+CONFIG_RTE_LIBRTE_EVENTDEV=n
+CONFIG_RTE_LIBRTE_EVENTDEV_DEBUG=n
+CONFIG_RTE_EVENT_MAX_DEVS=16
+CONFIG_RTE_EVENT_MAX_QUEUES_PER_DEV=64
+CONFIG_RTE_EVENT_TIMER_ADAPTER_NUM_MAX=32
+CONFIG_RTE_EVENT_ETH_INTR_RING_SIZE=1024
+CONFIG_RTE_EVENT_CRYPTO_ADAPTER_MAX_INSTANCE=32
+CONFIG_RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE=32
+# Compile PMD for skeleton event device
+CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV=n
+CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV_DEBUG=n
+# Compile PMD for software event device
+CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV=n
+# Compile PMD for distributed software event device
+CONFIG_RTE_LIBRTE_PMD_DSW_EVENTDEV=n
+# Compile PMD for octeontx sso event device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF=n
+# Compile PMD for OPDL event device
+CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV=n
+# Compile PMD for NXP DPAA event device
+CONFIG_RTE_LIBRTE_PMD_DPAA_EVENTDEV=n
+# Compile PMD for NXP DPAA2 event device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=n
+# Compile raw device support
+# EXPERIMENTAL: API may change without prior notice
+CONFIG_RTE_LIBRTE_RAWDEV=n
+CONFIG_RTE_RAWDEV_MAX_DEVS=10
+CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=n
+# Compile PMD for NXP DPAA2 CMDIF raw device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=n
+# Compile PMD for NXP DPAA2 QDMA raw device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+# Compile PMD for Intel FPGA raw device
+CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=n
+# Compile librte_ring
+CONFIG_RTE_LIBRTE_RING=y
+# Compile librte_mempool
+CONFIG_RTE_LIBRTE_MEMPOOL=y
+CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
+CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
+# Compile Mempool drivers
+CONFIG_RTE_DRIVER_MEMPOOL_BUCKET=y
+CONFIG_RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB=64
+CONFIG_RTE_DRIVER_MEMPOOL_RING=y
+CONFIG_RTE_DRIVER_MEMPOOL_STACK=y
+# Compile PMD for octeontx fpa mempool device
+CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOOL=n
+# Compile librte_mbuf
+CONFIG_RTE_LIBRTE_MBUF=y
+CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
+CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="ring_mp_mc"
+CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
+CONFIG_RTE_PKTMBUF_HEADROOM=128
+# Compile librte_timer
+CONFIG_RTE_LIBRTE_TIMER=n
+CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
+# Compile librte_cfgfile
+CONFIG_RTE_LIBRTE_CFGFILE=n
+# Compile librte_cmdline
+CONFIG_RTE_LIBRTE_CMDLINE=y
+CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
+# Compile librte_hash
+CONFIG_RTE_LIBRTE_HASH=y
+CONFIG_RTE_LIBRTE_HASH_DEBUG=n
+# Compile librte_efd
+CONFIG_RTE_LIBRTE_EFD=n
+# Compile librte_member
+CONFIG_RTE_LIBRTE_MEMBER=y
+# Compile librte_jobstats
+CONFIG_RTE_LIBRTE_JOBSTATS=n
+# Compile architecture we compile for. device metrics library
+CONFIG_RTE_LIBRTE_METRICS=y
+# Compile architecture we compile for. bitrate statistics library
+CONFIG_RTE_LIBRTE_BITRATE=y
+# Compile architecture we compile for. latency statistics library
+CONFIG_RTE_LIBRTE_LATENCY_STATS=y
+# Compile librte_telemetry
+CONFIG_RTE_LIBRTE_TELEMETRY=n
+# Compile librte_lpm
+CONFIG_RTE_LIBRTE_LPM=n
+CONFIG_RTE_LIBRTE_LPM_DEBUG=n
+# Compile librte_acl
+CONFIG_RTE_LIBRTE_ACL=n
+CONFIG_RTE_LIBRTE_ACL_DEBUG=n
+# Compile librte_power
+CONFIG_RTE_LIBRTE_POWER=n
+CONFIG_RTE_LIBRTE_POWER_DEBUG=n
+CONFIG_RTE_MAX_LCORE_FREQS=64
+# Compile librte_net
+CONFIG_RTE_LIBRTE_NET=y
+# Compile librte_ip_frag
+CONFIG_RTE_LIBRTE_IP_FRAG=y
+CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
+CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
+CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
+# Compile GRO library
+CONFIG_RTE_LIBRTE_GRO=y
+# Compile GSO library
+CONFIG_RTE_LIBRTE_GSO=y
+# Compile librte_meter
+CONFIG_RTE_LIBRTE_METER=y
+# Compile librte_classify
+CONFIG_RTE_LIBRTE_FLOW_CLASSIFY=n
+# Compile librte_sched
+CONFIG_RTE_LIBRTE_SCHED=n
+CONFIG_RTE_SCHED_DEBUG=n
+CONFIG_RTE_SCHED_RED=n
+CONFIG_RTE_SCHED_COLLECT_STATS=n
+CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
+CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
+CONFIG_RTE_SCHED_VECTOR=n
+# Compile architecture we compile for. distributor library
+CONFIG_RTE_LIBRTE_DISTRIBUTOR=n
+# Compile architecture we compile for. reorder library
+CONFIG_RTE_LIBRTE_REORDER=n
+# Compile librte_port
+CONFIG_RTE_LIBRTE_PORT=n
+CONFIG_RTE_PORT_STATS_COLLECT=n
+CONFIG_RTE_PORT_PCAP=n
+# Compile librte_table
+CONFIG_RTE_LIBRTE_TABLE=n
+CONFIG_RTE_TABLE_STATS_COLLECT=n
+# Compile librte_pipeline
+CONFIG_RTE_LIBRTE_PIPELINE=n
+CONFIG_RTE_PIPELINE_STATS_COLLECT=n
+# Compile librte_kni
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_LIBRTE_PMD_KNI=n
+CONFIG_RTE_KNI_KMOD=n
+CONFIG_RTE_KNI_KMOD_ETHTOOL=n
+CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
+# Compile architecture we compile for. pdump library
+CONFIG_RTE_LIBRTE_PDUMP=y
+# Compile vhost user library
+CONFIG_RTE_LIBRTE_VHOST=y
+CONFIG_RTE_LIBRTE_VHOST_NUMA=y
+CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
+# Compile vhost PMD
+# To compile, CONFIG_RTE_LIBRTE_VHOST should be enabled.
+CONFIG_RTE_LIBRTE_PMD_VHOST=y
+# Compile IFC driver
+# To compile, CONFIG_RTE_LIBRTE_VHOST and CONFIG_RTE_EAL_VFIO
+# should be enabled.
+CONFIG_RTE_LIBRTE_IFC_PMD=n
+# Compile librte_bpf
+CONFIG_RTE_LIBRTE_BPF=n
+# allow load BPF from ELF files (requires libelf)
+CONFIG_RTE_LIBRTE_BPF_ELF=n
+# Compile architecture we compile for. test application
+CONFIG_RTE_APP_TEST=y
+CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
+# Compile architecture we compile for. procinfo application
+CONFIG_RTE_PROC_INFO=y
+# Compile architecture we compile for. PMD test application
+CONFIG_RTE_TEST_PMD=n
+CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
+CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+# Compile architecture we compile for. bbdev test application
+CONFIG_RTE_TEST_BBDEV=n
+# Compile architecture we compile for. crypto performance application
+CONFIG_RTE_APP_CRYPTO_PERF=n
+# Compile architecture we compile for. eventdev application
+CONFIG_RTE_APP_EVENTDEV=n
+CONFIG_RTE_EXEC_ENV_LINUXAPP=y
+CONFIG_RTE_LIBRTE_VHOST_POSTCOPY=n
+# Common libraries, before Bus/PMDs
+# NXP DPAA BUS and drivers
+# NXP FSLMC BUS and DPAA2 drivers
+# NXP ENETC PMD Driver
+CONFIG_RTE_ARCH_PPC_64=y
+CONFIG_RTE_ARCH_64=y
+CONFIG_RTE_TOOLCHAIN_GCC=y
+# Note: Power doesn't have this support
+# Note: Initially, all of architecture we compile for. PMD drivers compilation are turned off on Power
+# Will turn on them only after architecture we compile for. successful testing on Power
+CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
diff --git a/SOURCES/set_config.sh b/SOURCES/set_config.sh
new file mode 100755
index 0000000..002386b
--- /dev/null
+++ b/SOURCES/set_config.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# Copyright (C) 2017, Red Hat, Inc.
+#
+# set_config.sh will copy a configuration from $1 to $2, in the process
+# checking that the sha header for $1 matches the header in $2
+
+source configlib.sh
+
+if (( $# < 2 )); then
+    echo "$0: source dest [comment-marker]"
+    exit 1
+fi
+
+if [ ! -f "$1" ]; then
+    echo "Source file $1 must exist."
+    exit 1
+fi
+src_file=$1
+shift
+
+if [ ! -f "$1" ]; then
+    echo "Dest file $1 must exist."
+    exit 1
+fi
+dst_file=$1
+shift
+
+comment_sep=${1:-#}
+
+export LANG=en_US.utf8
+
+DEST_FILE_SHA=""
+SRC_FILE_SHA=""
+
+calc_sha DEST_FILE_SHA "$dst_file" "$comment_sep" || echo "Failed to calc sha"
+retr_sha SRC_FILE_SHA "$src_file" "$comment_sep" || echo "Failed to retrieve sha"
+
+if [ "$DEST_FILE_SHA" != "$SRC_FILE_SHA" ]; then
+    echo "ERROR: The requisite starting sha from $dst_file does not match the"
+    echo "       specified sha in $src_file."
+    echo "[ $DEST_FILE_SHA ] vs [ $SRC_FILE_SHA ]"
+    exit 1
+fi
+
+mv "$dst_file" "$dst_file".OLD
+cp "$src_file" "$dst_file"
+echo "copied 1 config file."
+exit 0
diff --git a/SOURCES/x86_64-native-linuxapp-gcc-config b/SOURCES/x86_64-native-linuxapp-gcc-config
new file mode 100644
index 0000000..4b7a7ea
--- /dev/null
+++ b/SOURCES/x86_64-native-linuxapp-gcc-config
@@ -0,0 +1,525 @@
+# -*- cfg-sha: 2ba93102021dc5d38494cf5090c3ecaca37db13153dd558b1511a56f2a3d9b10
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2014 Intel Corporation
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2016 Intel Corporation
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2017 Intel Corporation
+# RTE_EXEC_ENV values are the directories in mk/exec-env/
+CONFIG_RTE_EXEC_ENV="linuxapp"
+# RTE_ARCH values are architecture we compile for. directories in mk/arch/
+CONFIG_RTE_ARCH="x86_64"
+# machine can define specific variables or action for a specific board
+# RTE_MACHINE values are architecture we compile for. directories in mk/machine/
+CONFIG_RTE_MACHINE="default"
+# The compiler we use.
+# RTE_TOOLCHAIN values are architecture we compile for. directories in mk/toolchain/
+CONFIG_RTE_TOOLCHAIN="gcc"
+# Use intrinsics or assembly code for key routines
+CONFIG_RTE_FORCE_INTRINSICS=n
+# Machine forces strict alignment constraints.
+CONFIG_RTE_ARCH_STRICT_ALIGN=n
+# Compile to share library
+CONFIG_RTE_BUILD_SHARED_LIB=n
+# Use newest code breaking previous ABI
+CONFIG_RTE_NEXT_ABI=n
+# Major ABI to overwrite library specific LIBABIVER
+CONFIG_RTE_MAJOR_ABI=
+# Machine's cache line size
+CONFIG_RTE_CACHE_LINE_SIZE=64
+# Memory model
+CONFIG_RTE_USE_C11_MEM_MODEL=n
+# Compile Environment Abstraction Layer
+CONFIG_RTE_LIBRTE_EAL=y
+CONFIG_RTE_MAX_LCORE=128
+CONFIG_RTE_MAX_NUMA_NODES=8
+CONFIG_RTE_MAX_HEAPS=32
+CONFIG_RTE_MAX_MEMSEG_LISTS=64
+# each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
+# or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
+CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
+CONFIG_RTE_MAX_MEM_MB_PER_LIST=32768
+# a "type" is a combination of page size and NUMA node. total number of memseg
+# lists per type will be limited to either RTE_MAX_MEMSEG_PER_TYPE pages (split
+# over multiple lists of RTE_MAX_MEMSEG_PER_LIST pages), or
+# RTE_MAX_MEM_MB_PER_TYPE megabytes of memory (split over multiple lists of
+# RTE_MAX_MEM_MB_PER_LIST), whichever is smaller
+CONFIG_RTE_MAX_MEMSEG_PER_TYPE=32768
+CONFIG_RTE_MAX_MEM_MB_PER_TYPE=131072
+# global maximum usable amount of VA, in megabytes
+CONFIG_RTE_MAX_MEM_MB=524288
+CONFIG_RTE_MAX_MEMZONE=2560
+CONFIG_RTE_MAX_TAILQ=32
+CONFIG_RTE_ENABLE_ASSERT=n
+CONFIG_RTE_LOG_DP_LEVEL=RTE_LOG_INFO
+CONFIG_RTE_LOG_HISTORY=256
+CONFIG_RTE_BACKTRACE=y
+CONFIG_RTE_LIBEAL_USE_HPET=n
+CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
+CONFIG_RTE_EAL_IGB_UIO=n
+CONFIG_RTE_EAL_VFIO=y
+CONFIG_RTE_MAX_VFIO_GROUPS=64
+CONFIG_RTE_MAX_VFIO_CONTAINERS=64
+CONFIG_RTE_MALLOC_DEBUG=n
+CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=y
+CONFIG_RTE_USE_LIBBSD=n
+# Recognize/ignore architecture we compile for. AVX/AVX512 CPU flags for performance/power testing.
+# AVX512 is marked as experimental for now, will enable it after enough
+# field test and possible optimization.
+CONFIG_RTE_ENABLE_AVX=y
+CONFIG_RTE_ENABLE_AVX512=n
+# Default driver path (or "" to disable)
+CONFIG_RTE_EAL_PMD_PATH=""
+# Compile Environment Abstraction Layer to support Vmware TSC map
+CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
+# Compile architecture we compile for. PCI library
+CONFIG_RTE_LIBRTE_PCI=y
+# Compile architecture we compile for. argument parser library
+CONFIG_RTE_LIBRTE_KVARGS=y
+# Compile generic ethernet library
+CONFIG_RTE_LIBRTE_ETHER=y
+CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
+CONFIG_RTE_MAX_ETHPORTS=32
+CONFIG_RTE_MAX_QUEUES_PER_PORT=1024
+CONFIG_RTE_LIBRTE_IEEE1588=n
+CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
+CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
+CONFIG_RTE_ETHDEV_PROFILE_WITH_VTUNE=n
+# Turn off Tx preparation stage
+# Warning: rte_eth_tx_prepare() can be safely disabled only if using a
+# driver which do not implement any Tx preparation.
+CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
+# Common libraries, before Bus/PMDs
+CONFIG_RTE_LIBRTE_COMMON_DPAAX=n
+# Compile architecture we compile for. Intel FPGA bus
+CONFIG_RTE_LIBRTE_IFPGA_BUS=n
+# Compile PCI bus driver
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+# Compile architecture we compile for. vdev bus
+CONFIG_RTE_LIBRTE_VDEV_BUS=y
+# Compile ARK PMD
+CONFIG_RTE_LIBRTE_ARK_PMD=n
+CONFIG_RTE_LIBRTE_ARK_PAD_TX=y
+CONFIG_RTE_LIBRTE_ARK_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_STATS=n
+CONFIG_RTE_LIBRTE_ARK_DEBUG_TRACE=n
+# Compile Aquantia Atlantic PMD driver
+CONFIG_RTE_LIBRTE_ATLANTIC_PMD=n
+# Compile AMD PMD
+CONFIG_RTE_LIBRTE_AXGBE_PMD=n
+CONFIG_RTE_LIBRTE_AXGBE_PMD_DEBUG=n
+# Compile burst-oriented Broadcom PMD driver
+CONFIG_RTE_LIBRTE_BNX2X_PMD=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_BNX2X_MF_SUPPORT=n
+CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC=n
+# Compile burst-oriented Broadcom BNXT PMD driver
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+# Compile burst-oriented Chelsio Terminator (CXGBE) PMD
+CONFIG_RTE_LIBRTE_CXGBE_PMD=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_REG=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_CXGBE_TPUT=y
+# NXP DPAA Bus
+CONFIG_RTE_LIBRTE_DPAA_BUS=n
+CONFIG_RTE_LIBRTE_DPAA_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA_PMD=n
+CONFIG_RTE_LIBRTE_DPAA_HWDEBUG=n
+# Compile NXP DPAA2 FSL-MC Bus
+CONFIG_RTE_LIBRTE_FSLMC_BUS=n
+# Compile Support Libraries for NXP DPAA2
+CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL=n
+CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=y
+# Compile burst-oriented NXP DPAA2 PMD driver
+CONFIG_RTE_LIBRTE_DPAA2_PMD=n
+CONFIG_RTE_LIBRTE_DPAA2_DEBUG_DRIVER=n
+# Compile NXP ENETC PMD Driver
+CONFIG_RTE_LIBRTE_ENETC_PMD=n
+# Compile burst-oriented Amazon ENA PMD driver
+CONFIG_RTE_LIBRTE_ENA_PMD=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_ENA_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_ENA_COM_DEBUG=n
+# Compile burst-oriented Cisco ENIC PMD driver
+CONFIG_RTE_LIBRTE_ENIC_PMD=y
+# Compile burst-oriented IGB & EM PMD drivers
+CONFIG_RTE_LIBRTE_EM_PMD=n
+CONFIG_RTE_LIBRTE_IGB_PMD=y
+CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
+# Compile burst-oriented IXGBE PMD driver
+CONFIG_RTE_LIBRTE_IXGBE_PMD=y
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
+CONFIG_RTE_IXGBE_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_IXGBE_BYPASS=n
+# Compile burst-oriented I40E PMD driver
+CONFIG_RTE_LIBRTE_I40E_PMD=y
+CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
+CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
+CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4
+# Compile burst-oriented FM10K PMD
+CONFIG_RTE_LIBRTE_FM10K_PMD=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_FM10K_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE=y
+CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
+# Compile burst-oriented AVF PMD driver
+CONFIG_RTE_LIBRTE_AVF_PMD=n
+CONFIG_RTE_LIBRTE_AVF_INC_VECTOR=y
+CONFIG_RTE_LIBRTE_AVF_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_AVF_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_AVF_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_AVF_16BYTE_RX_DESC=n
+# Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
+CONFIG_RTE_LIBRTE_MLX4_PMD=y
+CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS=y
+# Compile burst-oriented Mellanox ConnectX-4, ConnectX-5 & Bluefield
+# (MLX5) PMD
+CONFIG_RTE_LIBRTE_MLX5_PMD=y
+CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
+CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS=y
+# Compile burst-oriented Netronome NFP PMD driver
+CONFIG_RTE_LIBRTE_NFP_PMD=y
+CONFIG_RTE_LIBRTE_NFP_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_NFP_DEBUG_RX=n
+# QLogic 10G/25G/40G/50G/100G PMD
+CONFIG_RTE_LIBRTE_QEDE_PMD=y
+CONFIG_RTE_LIBRTE_QEDE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_QEDE_DEBUG_RX=n
+#Provides abs path/name of architecture we compile for. firmware file.
+#Empty string denotes driver will use default firmware
+CONFIG_RTE_LIBRTE_QEDE_FW=""
+# Compile burst-oriented Solarflare libefx-based PMD
+CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
+CONFIG_RTE_LIBRTE_SFC_EFX_DEBUG=n
+# Compile software PMD backed by SZEDATA2 device
+CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
+# Compile burst-oriented Cavium Thunderx NICVF PMD driver
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD=n
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX=n
+# Compile burst-oriented Cavium LiquidIO PMD driver
+CONFIG_RTE_LIBRTE_LIO_PMD=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_MBOX=n
+CONFIG_RTE_LIBRTE_LIO_DEBUG_REGS=n
+# Compile burst-oriented Cavium OCTEONTX network PMD driver
+CONFIG_RTE_LIBRTE_OCTEONTX_PMD=n
+# Compile WRS accelerated virtual port (AVP) guest PMD driver
+CONFIG_RTE_LIBRTE_AVP_PMD=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_AVP_DEBUG_BUFFERS=n
+# Compile burst-oriented VIRTIO PMD driver
+CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
+# Compile virtio device emulation inside virtio PMD driver
+CONFIG_RTE_VIRTIO_USER=n
+# Compile burst-oriented VMXNET3 PMD driver
+CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
+# Compile software PMD backed by AF_PACKET sockets (Linux only)
+CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
+# Compile link bonding PMD library
+CONFIG_RTE_LIBRTE_PMD_BOND=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
+CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
+# Compile fail-safe PMD
+CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y
+# Compile Marvell PMD driver
+CONFIG_RTE_LIBRTE_MVPP2_PMD=n
+# Compile Marvell MVNETA PMD driver
+CONFIG_RTE_LIBRTE_MVNETA_PMD=n
+# Compile support for VMBus library
+CONFIG_RTE_LIBRTE_VMBUS=y
+# Compile native PMD for Hyper-V/Azure
+CONFIG_RTE_LIBRTE_NETVSC_PMD=y
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_NETVSC_DEBUG_DUMP=n
+# Compile virtual device driver for NetVSC on Hyper-V/Azure
+CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD=y
+# Compile null PMD
+CONFIG_RTE_LIBRTE_PMD_NULL=n
+# Compile software PMD backed by PCAP files
+CONFIG_RTE_LIBRTE_PMD_PCAP=n
+# Compile example software rings based PMD
+CONFIG_RTE_LIBRTE_PMD_RING=y
+CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
+CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
+# Compile SOFTNIC PMD
+CONFIG_RTE_LIBRTE_PMD_SOFTNIC=n
+# Compile architecture we compile for. TAP PMD
+# It is enabled by default for Linux only.
+CONFIG_RTE_LIBRTE_PMD_TAP=y
+# Do prefetch of packet data within PMD driver receive function
+CONFIG_RTE_PMD_PACKET_PREFETCH=y
+# Compile generic wireless base band device library
+# EXPERIMENTAL: API may change without prior notice
+CONFIG_RTE_LIBRTE_BBDEV=n
+CONFIG_RTE_BBDEV_MAX_DEVS=128
+CONFIG_RTE_BBDEV_OFFLOAD_COST=n
+# Compile PMD for NULL bbdev device
+CONFIG_RTE_LIBRTE_PMD_BBDEV_NULL=y
+# Compile PMD for turbo software bbdev device
+CONFIG_RTE_LIBRTE_PMD_BBDEV_TURBO_SW=n
+# Compile generic crypto device library
+CONFIG_RTE_LIBRTE_CRYPTODEV=n
+CONFIG_RTE_CRYPTO_MAX_DEVS=64
+# Compile PMD for ARMv8 Crypto device
+CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO=n
+CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO_DEBUG=n
+# Compile NXP CAAM JR crypto Driver
+CONFIG_RTE_LIBRTE_PMD_CAAM_JR=n
+CONFIG_RTE_LIBRTE_PMD_CAAM_JR_BE=n
+# Compile NXP DPAA2 crypto sec driver for CAAM HW
+CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=n
+# NXP DPAA caam - crypto driver
+CONFIG_RTE_LIBRTE_PMD_DPAA_SEC=n
+CONFIG_RTE_LIBRTE_DPAA_MAX_CRYPTODEV=4
+# Compile PMD for Cavium OCTEON TX crypto device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_CRYPTO=y
+# Compile PMD for QuickAssist based devices - see docs for details
+CONFIG_RTE_LIBRTE_PMD_QAT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_SYM=n
+# Max. number of QuickAssist devices, which can be detected and attached
+CONFIG_RTE_PMD_QAT_MAX_PCI_DEVICES=48
+CONFIG_RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS=16
+CONFIG_RTE_PMD_QAT_COMP_IM_BUFFER_SIZE=65536
+# Compile PMD for virtio crypto devices
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO=n
+# Number of maximum virtio crypto devices
+CONFIG_RTE_MAX_VIRTIO_CRYPTO=32
+# Compile PMD for AESNI backed device
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
+# Compile PMD for Software backed device
+CONFIG_RTE_LIBRTE_PMD_OPENSSL=n
+# Compile PMD for AESNI GCM device
+CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n
+# Compile PMD for SNOW 3G device
+CONFIG_RTE_LIBRTE_PMD_SNOW3G=n
+CONFIG_RTE_LIBRTE_PMD_SNOW3G_DEBUG=n
+# Compile PMD for KASUMI device
+CONFIG_RTE_LIBRTE_PMD_KASUMI=n
+# Compile PMD for ZUC device
+CONFIG_RTE_LIBRTE_PMD_ZUC=n
+# Compile PMD for Crypto Scheduler device
+CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER=n
+# Compile PMD for NULL Crypto device
+CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO=n
+# Compile PMD for AMD CCP crypto device
+CONFIG_RTE_LIBRTE_PMD_CCP=n
+# Compile PMD for Marvell Crypto device
+CONFIG_RTE_LIBRTE_PMD_MVSAM_CRYPTO=n
+# Compile generic security library
+CONFIG_RTE_LIBRTE_SECURITY=n
+# Compile generic compression device library
+CONFIG_RTE_LIBRTE_COMPRESSDEV=n
+CONFIG_RTE_COMPRESS_MAX_DEVS=64
+# Compile compressdev unit test
+CONFIG_RTE_COMPRESSDEV_TEST=n
+# Compile PMD for Octeontx ZIPVF compression device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_ZIPVF=n
+# Compile PMD for ISA-L compression device
+CONFIG_RTE_LIBRTE_PMD_ISAL=n
+# Compile PMD for ZLIB compression device
+CONFIG_RTE_LIBRTE_PMD_ZLIB=n
+# Compile generic event device library
+CONFIG_RTE_LIBRTE_EVENTDEV=n
+CONFIG_RTE_LIBRTE_EVENTDEV_DEBUG=n
+CONFIG_RTE_EVENT_MAX_DEVS=16
+CONFIG_RTE_EVENT_MAX_QUEUES_PER_DEV=64
+CONFIG_RTE_EVENT_TIMER_ADAPTER_NUM_MAX=32
+CONFIG_RTE_EVENT_ETH_INTR_RING_SIZE=1024
+CONFIG_RTE_EVENT_CRYPTO_ADAPTER_MAX_INSTANCE=32
+CONFIG_RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE=32
+# Compile PMD for skeleton event device
+CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV=n
+CONFIG_RTE_LIBRTE_PMD_SKELETON_EVENTDEV_DEBUG=n
+# Compile PMD for software event device
+CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV=n
+# Compile PMD for distributed software event device
+CONFIG_RTE_LIBRTE_PMD_DSW_EVENTDEV=n
+# Compile PMD for octeontx sso event device
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX_SSOVF=n
+# Compile PMD for OPDL event device
+CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV=n
+# Compile PMD for NXP DPAA event device
+CONFIG_RTE_LIBRTE_PMD_DPAA_EVENTDEV=n
+# Compile PMD for NXP DPAA2 event device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV=n
+# Compile raw device support
+# EXPERIMENTAL: API may change without prior notice
+CONFIG_RTE_LIBRTE_RAWDEV=n
+CONFIG_RTE_RAWDEV_MAX_DEVS=10
+CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=n
+# Compile PMD for NXP DPAA2 CMDIF raw device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV=n
+# Compile PMD for NXP DPAA2 QDMA raw device
+CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
+# Compile PMD for Intel FPGA raw device
+CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=n
+# Compile librte_ring
+CONFIG_RTE_LIBRTE_RING=y
+# Compile librte_mempool
+CONFIG_RTE_LIBRTE_MEMPOOL=y
+CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
+CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
+# Compile Mempool drivers
+CONFIG_RTE_DRIVER_MEMPOOL_BUCKET=y
+CONFIG_RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB=64
+CONFIG_RTE_DRIVER_MEMPOOL_RING=y
+CONFIG_RTE_DRIVER_MEMPOOL_STACK=y
+# Compile PMD for octeontx fpa mempool device
+CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOOL=n
+# Compile librte_mbuf
+CONFIG_RTE_LIBRTE_MBUF=y
+CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
+CONFIG_RTE_MBUF_DEFAULT_MEMPOOL_OPS="ring_mp_mc"
+CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
+CONFIG_RTE_PKTMBUF_HEADROOM=128
+# Compile librte_timer
+CONFIG_RTE_LIBRTE_TIMER=n
+CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
+# Compile librte_cfgfile
+CONFIG_RTE_LIBRTE_CFGFILE=n
+# Compile librte_cmdline
+CONFIG_RTE_LIBRTE_CMDLINE=y
+CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
+# Compile librte_hash
+CONFIG_RTE_LIBRTE_HASH=y
+CONFIG_RTE_LIBRTE_HASH_DEBUG=n
+# Compile librte_efd
+CONFIG_RTE_LIBRTE_EFD=n
+# Compile librte_member
+CONFIG_RTE_LIBRTE_MEMBER=y
+# Compile librte_jobstats
+CONFIG_RTE_LIBRTE_JOBSTATS=n
+# Compile architecture we compile for. device metrics library
+CONFIG_RTE_LIBRTE_METRICS=y
+# Compile architecture we compile for. bitrate statistics library
+CONFIG_RTE_LIBRTE_BITRATE=y
+# Compile architecture we compile for. latency statistics library
+CONFIG_RTE_LIBRTE_LATENCY_STATS=y
+# Compile librte_telemetry
+CONFIG_RTE_LIBRTE_TELEMETRY=n
+# Compile librte_lpm
+CONFIG_RTE_LIBRTE_LPM=n
+CONFIG_RTE_LIBRTE_LPM_DEBUG=n
+# Compile librte_acl
+CONFIG_RTE_LIBRTE_ACL=n
+CONFIG_RTE_LIBRTE_ACL_DEBUG=n
+# Compile librte_power
+CONFIG_RTE_LIBRTE_POWER=n
+CONFIG_RTE_LIBRTE_POWER_DEBUG=n
+CONFIG_RTE_MAX_LCORE_FREQS=64
+# Compile librte_net
+CONFIG_RTE_LIBRTE_NET=y
+# Compile librte_ip_frag
+CONFIG_RTE_LIBRTE_IP_FRAG=y
+CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=n
+CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=4
+CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
+# Compile GRO library
+CONFIG_RTE_LIBRTE_GRO=y
+# Compile GSO library
+CONFIG_RTE_LIBRTE_GSO=y
+# Compile librte_meter
+CONFIG_RTE_LIBRTE_METER=y
+# Compile librte_classify
+CONFIG_RTE_LIBRTE_FLOW_CLASSIFY=n
+# Compile librte_sched
+CONFIG_RTE_LIBRTE_SCHED=n
+CONFIG_RTE_SCHED_DEBUG=n
+CONFIG_RTE_SCHED_RED=n
+CONFIG_RTE_SCHED_COLLECT_STATS=n
+CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
+CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
+CONFIG_RTE_SCHED_VECTOR=n
+# Compile architecture we compile for. distributor library
+CONFIG_RTE_LIBRTE_DISTRIBUTOR=n
+# Compile architecture we compile for. reorder library
+CONFIG_RTE_LIBRTE_REORDER=n
+# Compile librte_port
+CONFIG_RTE_LIBRTE_PORT=n
+CONFIG_RTE_PORT_STATS_COLLECT=n
+CONFIG_RTE_PORT_PCAP=n
+# Compile librte_table
+CONFIG_RTE_LIBRTE_TABLE=n
+CONFIG_RTE_TABLE_STATS_COLLECT=n
+# Compile librte_pipeline
+CONFIG_RTE_LIBRTE_PIPELINE=n
+CONFIG_RTE_PIPELINE_STATS_COLLECT=n
+# Compile librte_kni
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_LIBRTE_PMD_KNI=n
+CONFIG_RTE_KNI_KMOD=n
+CONFIG_RTE_KNI_KMOD_ETHTOOL=n
+CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
+# Compile architecture we compile for. pdump library
+CONFIG_RTE_LIBRTE_PDUMP=y
+# Compile vhost user library
+CONFIG_RTE_LIBRTE_VHOST=y
+CONFIG_RTE_LIBRTE_VHOST_NUMA=y
+CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
+# Compile vhost PMD
+# To compile, CONFIG_RTE_LIBRTE_VHOST should be enabled.
+CONFIG_RTE_LIBRTE_PMD_VHOST=y
+# Compile IFC driver
+# To compile, CONFIG_RTE_LIBRTE_VHOST and CONFIG_RTE_EAL_VFIO
+# should be enabled.
+CONFIG_RTE_LIBRTE_IFC_PMD=n
+# Compile librte_bpf
+CONFIG_RTE_LIBRTE_BPF=n
+# allow load BPF from ELF files (requires libelf)
+CONFIG_RTE_LIBRTE_BPF_ELF=n
+# Compile architecture we compile for. test application
+CONFIG_RTE_APP_TEST=y
+CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
+# Compile architecture we compile for. procinfo application
+CONFIG_RTE_PROC_INFO=y
+# Compile architecture we compile for. PMD test application
+CONFIG_RTE_TEST_PMD=n
+CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
+CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+# Compile architecture we compile for. bbdev test application
+CONFIG_RTE_TEST_BBDEV=n
+# Compile architecture we compile for. crypto performance application
+CONFIG_RTE_APP_CRYPTO_PERF=n
+# Compile architecture we compile for. eventdev application
+CONFIG_RTE_APP_EVENTDEV=n
+CONFIG_RTE_EXEC_ENV_LINUXAPP=y
+CONFIG_RTE_LIBRTE_VHOST_POSTCOPY=n
+# Common libraries, before Bus/PMDs
+# NXP DPAA BUS and drivers
+# NXP FSLMC BUS and DPAA2 drivers
+# NXP ENETC PMD Driver
+CONFIG_RTE_ARCH_X86_64=y
+CONFIG_RTE_ARCH_X86=y
+CONFIG_RTE_ARCH_64=y
+CONFIG_RTE_TOOLCHAIN_GCC=y
+CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
diff --git a/SPECS/ovn22.03.spec b/SPECS/ovn22.03.spec
new file mode 100644
index 0000000..4da4fd4
--- /dev/null
+++ b/SPECS/ovn22.03.spec
@@ -0,0 +1,625 @@
+# Copyright (C) 2009, 2010, 2013, 2014 Nicira Networks, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.  This file is offered as-is,
+# without warranty of any kind.
+#
+# If tests have to be skipped while building, specify the '--without check'
+# option. For example:
+# rpmbuild -bb --without check rhel/openvswitch-fedora.spec
+
+# This defines the base package name's version.
+
+%define pkgver 2.13
+%define pkgname ovn22.03
+
+# If libcap-ng isn't available and there is no need for running OVS
+# as regular user, specify the '--without libcapng'
+%bcond_without libcapng
+
+# Enable PIE, bz#955181
+%global _hardened_build 1
+
+# RHEL-7 doesn't define _rundir macro yet
+# Fedora 15 onwards uses /run as _rundir
+%if 0%{!?_rundir:1}
+%define _rundir /run
+%endif
+
+# Build python2 (that provides python) and python3 subpackages on Fedora
+# Build only python3 (that provides python) subpackage on RHEL8
+# Build only python subpackage on RHEL7
+%if 0%{?rhel} > 7 || 0%{?fedora}
+# On RHEL8 Sphinx is included in buildroot
+%global external_sphinx 1
+%else
+# Don't use external sphinx (RHV doesn't have optional repositories enabled)
+%global external_sphinx 0
+%endif
+
+# We would see rpmlinit error - E: hardcoded-library-path in '% {_prefix}/lib'.
+# But there is no solution to fix this. Using {_lib} macro will solve the
+# rpmlink error, but will install the files in /usr/lib64/.
+# OVN pacemaker ocf script file is copied in /usr/lib/ocf/resource.d/ovn/
+# and we are not sure if pacemaker looks into this path to find the
+# OVN resource agent script.
+%global ovnlibdir %{_prefix}/lib
+
+Name: %{pkgname}
+Summary: Open Virtual Network support
+Group: System Environment/Daemons
+URL: http://www.ovn.org/
+Version: 22.03.0
+Release: 22%{?commit0:.%{date}git%{shortcommit0}}%{?dist}
+Provides: openvswitch%{pkgver}-ovn-common = %{?epoch:%{epoch}:}%{version}-%{release}
+Obsoletes: openvswitch%{pkgver}-ovn-common < 2.11.0-1
+
+# Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
+# lib/sflow*.[ch] files are SISSL
+License: ASL 2.0 and LGPLv2+ and SISSL
+
+# Always pull an upstream release, since this is what we rebase to.
+Source: https://github.com/ovn-org/ovn/archive/v%{version}.tar.gz#/ovn-%{version}.tar.gz
+
+%define ovscommit ba159ee0f97ed770c244cd6710d34fe20595541d
+%define ovsshortcommit ba159ee
+
+Source10: https://github.com/openvswitch/ovs/archive/%{ovscommit}.tar.gz#/openvswitch-%{ovsshortcommit}.tar.gz
+%define ovsdir ovs-%{ovscommit}
+
+%define docutilsver 0.12
+%define pygmentsver 1.4
+%define sphinxver   1.1.3
+Source100: https://pypi.io/packages/source/d/docutils/docutils-%{docutilsver}.tar.gz
+Source101: https://pypi.io/packages/source/P/Pygments/Pygments-%{pygmentsver}.tar.gz
+Source102: https://pypi.io/packages/source/S/Sphinx/Sphinx-%{sphinxver}.tar.gz
+
+Source500: configlib.sh
+Source501: gen_config_group.sh
+Source502: set_config.sh
+
+# Important: source503 is used as the actual copy file
+# @TODO: this causes a warning - fix it?
+Source504: arm64-armv8a-linuxapp-gcc-config
+Source505: ppc_64-power8-linuxapp-gcc-config
+Source506: x86_64-native-linuxapp-gcc-config
+
+Patch:     %{pkgname}.patch
+
+# FIXME Sphinx is used to generate some manpages, unfortunately, on RHEL, it's
+# in the -optional repository and so we can't require it directly since RHV
+# doesn't have the -optional repository enabled and so TPS fails
+%if %{external_sphinx}
+BuildRequires: python3-sphinx
+%else
+# Sphinx dependencies
+BuildRequires: python-devel
+BuildRequires: python-setuptools
+#BuildRequires: python2-docutils
+BuildRequires: python-jinja2
+BuildRequires: python-nose
+#BuildRequires: python2-pygments
+# docutils dependencies
+BuildRequires: python-imaging
+# pygments dependencies
+BuildRequires: python-nose
+%endif
+
+BuildRequires: gcc gcc-c++ make
+BuildRequires: autoconf automake libtool
+BuildRequires: systemd-units openssl openssl-devel
+BuildRequires: python3-devel python3-setuptools
+BuildRequires: desktop-file-utils
+BuildRequires: groff-base graphviz
+BuildRequires: unbound-devel
+
+# make check dependencies
+BuildRequires: procps-ng
+%if 0%{?rhel} == 8 || 0%{?fedora}
+BuildRequires: python3-pyOpenSSL
+%endif
+BuildRequires: tcpdump
+
+%if %{with libcapng}
+BuildRequires: libcap-ng libcap-ng-devel
+%endif
+
+Requires: hostname openssl iproute module-init-tools
+
+Requires(post): systemd-units
+Requires(preun): systemd-units
+Requires(postun): systemd-units
+
+# to skip running checks, pass --without check
+%bcond_without check
+
+%description
+OVN, the Open Virtual Network, is a system to support virtual network
+abstraction.  OVN complements the existing capabilities of OVS to add
+native support for virtual network abstractions, such as virtual L2 and L3
+overlays and security groups.
+
+%package central
+Summary: Open Virtual Network support
+License: ASL 2.0
+Requires: %{pkgname}
+Requires: firewalld-filesystem
+Provides: openvswitch%{pkgver}-ovn-central = %{?epoch:%{epoch}:}%{version}-%{release}
+Obsoletes: openvswitch%{pkgver}-ovn-central < 2.11.0-1
+
+%description central
+OVN DB servers and ovn-northd running on a central node.
+
+%package host
+Summary: Open Virtual Network support
+License: ASL 2.0
+Requires: %{pkgname}
+Requires: firewalld-filesystem
+Provides: openvswitch%{pkgver}-ovn-host = %{?epoch:%{epoch}:}%{version}-%{release}
+Obsoletes: openvswitch%{pkgver}-ovn-host < 2.11.0-1
+
+%description host
+OVN controller running on each host.
+
+%package vtep
+Summary: Open Virtual Network support
+License: ASL 2.0
+Requires: %{pkgname}
+Provides: openvswitch%{pkgver}-ovn-vtep = %{?epoch:%{epoch}:}%{version}-%{release}
+Obsoletes: openvswitch%{pkgver}-ovn-vtep < 2.11.0-1
+
+%description vtep
+OVN vtep controller
+
+%prep
+%if 0%{?commit0:1}
+%autosetup -n ovn-%{commit0} -a 10 -p 1
+%else
+%autosetup -n ovn-%{version} -a 10 -p 1
+%endif
+
+%build
+%if 0%{?commit0:1}
+# fix the snapshot unreleased version to be the released one.
+sed -i.old -e "s/^AC_INIT(openvswitch,.*,/AC_INIT(openvswitch, %{version},/" configure.ac
+%endif
+./boot.sh
+
+# OVN source code is now separate.
+# Build openvswitch first.
+# XXX Current openvswitch2.13 doesn't
+# use "2.13.0" for version. It's a commit hash
+pushd %{ovsdir}
+./boot.sh
+%configure \
+%if %{with libcapng}
+        --enable-libcapng \
+%else
+        --disable-libcapng \
+%endif
+        --enable-ssl \
+        --with-pkidir=%{_sharedstatedir}/openvswitch/pki
+
+make %{?_smp_mflags}
+popd
+
+# Build OVN.
+# XXX OVS version needs to be updated when ovs2.13 is updated.
+%configure \
+        --with-ovs-source=$PWD/%{ovsdir} \
+%if %{with libcapng}
+        --enable-libcapng \
+%else
+        --disable-libcapng \
+%endif
+        --enable-ssl \
+        --with-pkidir=%{_sharedstatedir}/openvswitch/pki
+
+make %{?_smp_mflags}
+
+%install
+%make_install
+install -p -D -m 0644 \
+        rhel/usr_share_ovn_scripts_systemd_sysconfig.template \
+        $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/ovn
+
+for service in ovn-controller ovn-controller-vtep ovn-northd; do
+        install -p -D -m 0644 \
+                        rhel/usr_lib_systemd_system_${service}.service \
+                        $RPM_BUILD_ROOT%{_unitdir}/${service}.service
+done
+
+install -d -m 0755 $RPM_BUILD_ROOT/%{_sharedstatedir}/ovn
+
+install -d $RPM_BUILD_ROOT%{ovnlibdir}/firewalld/services/
+install -p -m 0644 rhel/usr_lib_firewalld_services_ovn-central-firewall-service.xml \
+        $RPM_BUILD_ROOT%{ovnlibdir}/firewalld/services/ovn-central-firewall-service.xml
+install -p -m 0644 rhel/usr_lib_firewalld_services_ovn-host-firewall-service.xml \
+        $RPM_BUILD_ROOT%{ovnlibdir}/firewalld/services/ovn-host-firewall-service.xml
+
+install -d -m 0755 $RPM_BUILD_ROOT%{ovnlibdir}/ocf/resource.d/ovn
+ln -s %{_datadir}/ovn/scripts/ovndb-servers.ocf \
+      $RPM_BUILD_ROOT%{ovnlibdir}/ocf/resource.d/ovn/ovndb-servers
+
+install -p -D -m 0644 rhel/etc_logrotate.d_ovn \
+        $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d/ovn
+
+# remove unneeded files.
+rm -f $RPM_BUILD_ROOT%{_bindir}/ovs*
+rm -f $RPM_BUILD_ROOT%{_bindir}/vtep-ctl
+rm -f $RPM_BUILD_ROOT%{_sbindir}/ovs*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man1/ovs*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man5/ovs*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man5/vtep*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man7/ovs*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man8/ovs*
+rm -f $RPM_BUILD_ROOT%{_mandir}/man8/vtep*
+rm -rf $RPM_BUILD_ROOT%{_datadir}/ovn/python
+rm -f $RPM_BUILD_ROOT%{_datadir}/ovn/scripts/ovs*
+rm -rf $RPM_BUILD_ROOT%{_datadir}/ovn/bugtool-plugins
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/*.pc
+rm -f $RPM_BUILD_ROOT%{_includedir}/ovn/*
+rm -f $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d/ovs-appctl-bashcomp.bash
+rm -f $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d/ovs-vsctl-bashcomp.bash
+rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/openvswitch
+rm -f $RPM_BUILD_ROOT%{_datadir}/ovn/scripts/ovn-bugtool*
+rm -f $RPM_BUILD_ROOT/%{_bindir}/ovn-docker-overlay-driver \
+        $RPM_BUILD_ROOT/%{_bindir}/ovn-docker-underlay-driver
+
+%check
+%if %{with check}
+    touch resolv.conf
+    export OVS_RESOLV_CONF=$(pwd)/resolv.conf
+    if ! make check TESTSUITEFLAGS='%{_smp_mflags}'; then
+        cat tests/testsuite.log
+        if ! make check TESTSUITEFLAGS='--recheck'; then
+            cat tests/testsuite.log
+            # Presently a test case - "2796: ovn -- ovn-controller incremental processing"
+            # is failing on aarch64 arch. Let's not exit for this arch
+            # until we figure out why it is failing.
+            # Test case 93: ovn.at:12105       ovn -- ACLs on Port Groups is failing
+            # repeatedly on s390x. This needs to be investigated.
+            %ifnarch aarch64
+            %ifnarch ppc64le
+            %ifnarch s390x
+                exit 1
+            %endif
+            %endif
+            %endif
+        fi
+    fi
+%endif
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%pre central
+if [ $1 -eq 1 ] ; then
+    # Package install.
+    /bin/systemctl status ovn-northd.service >/dev/null
+    ovn_status=$?
+    rpm -ql openvswitch-ovn-central > /dev/null
+    if [[ "$?" = "0" && "$ovn_status" = "0" ]]; then
+        # ovn-northd service is running which means old openvswitch-ovn-central
+        # is already installed and it will be cleaned up. So start ovn-northd
+        # service when posttrans central is called.
+        touch %{_localstatedir}/lib/rpm-state/ovn-northd
+    fi
+fi
+
+%pre host
+if [ $1 -eq 1 ] ; then
+    # Package install.
+    /bin/systemctl status ovn-controller.service >/dev/null
+    ovn_status=$?
+    rpm -ql openvswitch-ovn-host > /dev/null
+    if [[ "$?" = "0" && "$ovn_status" = "0" ]]; then
+        # ovn-controller service is running which means old
+        # openvswitch-ovn-host is installed and it will be cleaned up. So
+        # start ovn-controller service when posttrans host is called.
+        touch %{_localstatedir}/lib/rpm-state/ovn-controller
+    fi
+fi
+
+%pre vtep
+if [ $1 -eq 1 ] ; then
+    # Package install.
+    /bin/systemctl status ovn-controller-vtep.service >/dev/null
+    ovn_status=$?
+    rpm -ql openvswitch-ovn-vtep > /dev/null
+    if [[ "$?" = "0" && "$ovn_status" = "0" ]]; then
+        # ovn-controller-vtep service is running which means old
+        # openvswitch-ovn-vtep is installed and it will be cleaned up. So
+        # start ovn-controller-vtep service when posttrans host is called.
+        touch %{_localstatedir}/lib/rpm-state/ovn-controller-vtep
+    fi
+fi
+
+%preun central
+%if 0%{?systemd_preun:1}
+    %systemd_preun ovn-northd.service
+%else
+    if [ $1 -eq 0 ] ; then
+        # Package removal, not upgrade
+        /bin/systemctl --no-reload disable ovn-northd.service >/dev/null 2>&1 || :
+        /bin/systemctl stop ovn-northd.service >/dev/null 2>&1 || :
+    fi
+%endif
+
+%preun host
+%if 0%{?systemd_preun:1}
+    %systemd_preun ovn-controller.service
+%else
+    if [ $1 -eq 0 ] ; then
+        # Package removal, not upgrade
+        /bin/systemctl --no-reload disable ovn-controller.service >/dev/null 2>&1 || :
+        /bin/systemctl stop ovn-controller.service >/dev/null 2>&1 || :
+    fi
+%endif
+
+%preun vtep
+%if 0%{?systemd_preun:1}
+    %systemd_preun ovn-controller-vtep.service
+%else
+    if [ $1 -eq 0 ] ; then
+        # Package removal, not upgrade
+        /bin/systemctl --no-reload disable ovn-controller-vtep.service >/dev/null 2>&1 || :
+        /bin/systemctl stop ovn-controller-vtep.service >/dev/null 2>&1 || :
+    fi
+%endif
+
+%post
+%if %{with libcapng}
+if [ $1 -eq 1 ]; then
+    sed -i 's:^#OVN_USER_ID=:OVN_USER_ID=:' %{_sysconfdir}/sysconfig/ovn
+    sed -i 's:\(.*su\).*:\1 openvswitch openvswitch:' %{_sysconfdir}/logrotate.d/ovn
+fi
+%endif
+
+%post central
+%if 0%{?systemd_post:1}
+    %systemd_post ovn-northd.service
+%else
+    # Package install, not upgrade
+    if [ $1 -eq 1 ]; then
+        /bin/systemctl daemon-reload >dev/null || :
+    fi
+%endif
+
+%post host
+%if 0%{?systemd_post:1}
+    %systemd_post ovn-controller.service
+%else
+    # Package install, not upgrade
+    if [ $1 -eq 1 ]; then
+        /bin/systemctl daemon-reload >dev/null || :
+    fi
+%endif
+
+%post vtep
+%if 0%{?systemd_post:1}
+    %systemd_post ovn-controller-vtep.service
+%else
+    # Package install, not upgrade
+    if [ $1 -eq 1 ]; then
+        /bin/systemctl daemon-reload >dev/null || :
+    fi
+%endif
+
+%postun
+
+%postun central
+%if 0%{?systemd_postun_with_restart:1}
+    %systemd_postun_with_restart ovn-northd.service
+%else
+    /bin/systemctl daemon-reload >/dev/null 2>&1 || :
+    if [ "$1" -ge "1" ] ; then
+    # Package upgrade, not uninstall
+        /bin/systemctl try-restart ovn-northd.service >/dev/null 2>&1 || :
+    fi
+%endif
+
+%postun host
+%if 0%{?systemd_postun_with_restart:1}
+    %systemd_postun_with_restart ovn-controller.service
+%else
+    /bin/systemctl daemon-reload >/dev/null 2>&1 || :
+    if [ "$1" -ge "1" ] ; then
+        # Package upgrade, not uninstall
+        /bin/systemctl try-restart ovn-controller.service >/dev/null 2>&1 || :
+    fi
+%endif
+
+%postun vtep
+%if 0%{?systemd_postun_with_restart:1}
+    %systemd_postun_with_restart ovn-controller-vtep.service
+%else
+    /bin/systemctl daemon-reload >/dev/null 2>&1 || :
+    if [ "$1" -ge "1" ] ; then
+        # Package upgrade, not uninstall
+        /bin/systemctl try-restart ovn-controller-vtep.service >/dev/null 2>&1 || :
+    fi
+%endif
+
+%posttrans central
+if [ $1 -eq 1 ]; then
+    # Package install, not upgrade
+    if [ -e %{_localstatedir}/lib/rpm-state/ovn-northd ]; then
+        rm %{_localstatedir}/lib/rpm-state/ovn-northd
+        /bin/systemctl start ovn-northd.service >/dev/null 2>&1 || :
+    fi
+fi
+
+
+%posttrans host
+if [ $1 -eq 1 ]; then
+    # Package install, not upgrade
+    if [ -e %{_localstatedir}/lib/rpm-state/ovn-controller ]; then
+        rm %{_localstatedir}/lib/rpm-state/ovn-controller
+        /bin/systemctl start ovn-controller.service >/dev/null 2>&1 || :
+    fi
+fi
+
+%posttrans vtep
+if [ $1 -eq 1 ]; then
+    # Package install, not upgrade
+    if [ -e %{_localstatedir}/lib/rpm-state/ovn-controller-vtep ]; then
+        rm %{_localstatedir}/lib/rpm-state/ovn-controller-vtep
+        /bin/systemctl start ovn-controller-vtep.service >/dev/null 2>&1 || :
+    fi
+fi
+
+%files
+%{_bindir}/ovn-nbctl
+%{_bindir}/ovn-sbctl
+%{_bindir}/ovn-trace
+%{_bindir}/ovn-detrace
+%{_bindir}/ovn_detrace.py
+%{_bindir}/ovn-appctl
+%{_bindir}/ovn-ic-nbctl
+%{_bindir}/ovn-ic-sbctl
+%dir %{_datadir}/ovn/
+%dir %{_datadir}/ovn/scripts/
+%{_datadir}/ovn/scripts/ovn-ctl
+%{_datadir}/ovn/scripts/ovn-lib
+%{_datadir}/ovn/scripts/ovndb-servers.ocf
+%{_mandir}/man8/ovn-ctl.8*
+%{_mandir}/man8/ovn-appctl.8*
+%{_mandir}/man8/ovn-nbctl.8*
+%{_mandir}/man8/ovn-ic-nbctl.8*
+%{_mandir}/man8/ovn-trace.8*
+%{_mandir}/man1/ovn-detrace.1*
+%{_mandir}/man7/ovn-architecture.7*
+%{_mandir}/man8/ovn-sbctl.8*
+%{_mandir}/man8/ovn-ic-sbctl.8*
+%{_mandir}/man5/ovn-nb.5*
+%{_mandir}/man5/ovn-ic-nb.5*
+%{_mandir}/man5/ovn-sb.5*
+%{_mandir}/man5/ovn-ic-sb.5*
+%dir %{ovnlibdir}/ocf/resource.d/ovn/
+%{ovnlibdir}/ocf/resource.d/ovn/ovndb-servers
+%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/logrotate.d/ovn
+%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/sysconfig/ovn
+
+%files central
+%{_bindir}/ovn-northd
+%{_bindir}/ovn-ic
+%{_mandir}/man8/ovn-northd.8*
+%{_mandir}/man8/ovn-ic.8*
+%{_datadir}/ovn/ovn-nb.ovsschema
+%{_datadir}/ovn/ovn-ic-nb.ovsschema
+%{_datadir}/ovn/ovn-sb.ovsschema
+%{_datadir}/ovn/ovn-ic-sb.ovsschema
+%{_unitdir}/ovn-northd.service
+%{ovnlibdir}/firewalld/services/ovn-central-firewall-service.xml
+
+%files host
+%{_bindir}/ovn-controller
+%{_mandir}/man8/ovn-controller.8*
+%{_unitdir}/ovn-controller.service
+%{ovnlibdir}/firewalld/services/ovn-host-firewall-service.xml
+
+%files vtep
+%{_bindir}/ovn-controller-vtep
+%{_mandir}/man8/ovn-controller-vtep.8*
+%{_unitdir}/ovn-controller-vtep.service
+
+%changelog
+* Tue Apr 26 2022 Adrian Moreno <amorenoz@redhat.com> - 22.03.0-22
+- parallel-hmap: rewrite iterator using multivar helpers
+[Gerrit: 3da85a6660776548ddafaa9759b260b0dac38b4b]
+[Upstream: 3da85a6660776548ddafaa9759b260b0dac38b4b]
+
+* Tue Apr 26 2022 Adrian Moreno <amorenoz@redhat.com> - 22.03.0-21
+- treewide: bump ovs and fix problematic loops
+[Gerrit: 985ef4580ac6558859e104bad6fd5e2a68af79f7]
+[Upstream: 985ef4580ac6558859e104bad6fd5e2a68af79f7]
+
+* Tue Apr 26 2022 Mark Michelson <mmichels@redhat.com> - 22.03.0-20
+- Get OVS branch updated to proper base version for upcoming changes.
+[Gerrit: 367051dacab28dbe875aba9e1920b5693cf284c3]
+[Upstream: 367051dacab28dbe875aba9e1920b5693cf284c3]
+
+* Mon Apr 25 2022 Numan Siddique <numans@ovn.org> - 22.03.0-19
+- ovn-northd: Add flow to use eth.src if nd.tll is 0 in put_nd() action. (#2078026)
+[Gerrit: bd0ee4c1103ca5eaf834e48093205cacddaadf31]
+[Upstream: 80187a8031b6abe01fb23657a9bed2372ae23af5]
+
+* Thu Apr 21 2022 Ihar Hrachyshka <ihrachys@redhat.com> - 22.03.0-18
+- Stop sending garps when binding not bound to chassis
+[Gerrit: 65088824dbca07dfdf3402d1775d3af76a304ef4]
+[Upstream: 65088824dbca07dfdf3402d1775d3af76a304ef4]
+
+* Thu Apr 21 2022 Ales Musil <amusil@redhat.com> - 22.03.0-17
+- pinctrl.c: Send GARP only on chassis atached to l3gw (#2062580)
+[Gerrit: 77ec310dda51c78c1897011ba851612787fcc6c6]
+[Upstream: 77ec310dda51c78c1897011ba851612787fcc6c6]
+
+* Sun Apr 17 2022 Lorenzo Bianconi <lorenzo.bianconi@redhat.com> - 22.03.0-16
+- system-ovn: fix CoPP test failures (#2073060)
+[Gerrit: 388446ff27650773716ebcbc332424b1bf82bad1]
+[Upstream: e922c05dbb0c0ca70c98bd0b24833248ff5d458b]
+
+* Wed Apr 13 2022 Han Zhou <hzhou@ovn.org> - 22.03.0-15
+- ofctrl.c: Check installed flow when merging tracked flow changes. (#2071272)
+[Gerrit: 92cdada0e150e937e19f52c98a0c6a6dba7a84e0]
+[Upstream: 9c6d285ef2a65aef032cd60f9a9fe16cad7c4222]
+
+* Mon Apr 11 2022 Xavier Simonart <xsimonar@redhat.com> - 22.03.0-14
+- northd: avoid writing to IDL in parallel when using northd parallelization
+[Gerrit: 6410cb7906121bf2ebec3698d53bcfcb580ca4f6]
+[Upstream: 741a135fa1db9e10b725d4b69c6da455f732b89b]
+
+* Thu Apr 07 2022 Mohammad Heib <mheib@redhat.com> - 22.03.0-13
+- controller/pinctrl: avoid accessing invalid memory (#2052945)
+[Gerrit: 55a0ab5d2971daaf22e3d935f623bf7548a3df98]
+[Upstream: 6bc6002601ea161a287bcf53524e9282ab97c31b]
+
+* Thu Apr 07 2022 Xavier Simonart <xsimonar@redhat.com> - 22.03.0-12
+- northd: avoid snat on reply packets (#2061593)
+[Gerrit: be49d5145e10b1e4a525eed3b12d7ffb7818f2d1]
+[Upstream: 8b3e1afc30f3cf0ef9857fdc68f619b6fbed10dc]
+
+* Wed Apr 06 2022 Vladislav Odintsov <odivlad@gmail.com> - 22.03.0-11
+- vtep: correctly bring vtep lport up in SBDB
+[Gerrit: 655c3aa74d45791b0de5548c787ee24a147f2456]
+[Upstream: b35c98c923f4972198f741ff1d2b28671d6ff50d]
+
+* Wed Apr 06 2022 Lorenzo Bianconi <lorenzo.bianconi@redhat.com> - 22.03.0-10
+- controller: properly remove qos policy meters
+[Gerrit: a814b865fbec460c91f9b5037d936b9d518c7a2f]
+[Upstream: 1e1d75c725a3445a853dd792b28ff02bb3ab1218]
+
+* Wed Mar 30 2022 Mark Michelson <mmichels@redhat.com> - 22.03.0-9
+- tests: Make "check CoPP config" more reliable.
+[Gerrit: 93e21802ac27ed29f2a4daf58a10912ebd581db5]
+[Upstream: 93e21802ac27ed29f2a4daf58a10912ebd581db5]
+
+* Tue Mar 29 2022 Dumitru Ceara <dceara@redhat.com> - 22.03.0-8
+- inc-proc-eng: Properly log recompute reason.
+[Gerrit: 3b07a5db4abd921a87b6fdfb851cf27e6975b079]
+[Upstream: 3b07a5db4abd921a87b6fdfb851cf27e6975b079]
+
+* Thu Mar 24 2022 Mark Michelson <mmichels@redhat.com> - 22.03.0-7
+- NEWS: Update the 22.03.0 release date.
+[Gerrit: e62886efda51adadd6c01c4e7ee0bbd97994216c]
+[Upstream: e62886efda51adadd6c01c4e7ee0bbd97994216c]
+
+* Thu Mar 24 2022 Vladislav Odintsov <odivlad@gmail.com> - 22.03.0-6
+- rhel: fix logrotate user config option
+[Gerrit: 135310cae98e84a637f13e99439566846debcb29]
+[Upstream: e8800ddd9e919e2ffc9d8c5c9ab27f0a5a6ec2e5]
+
+* Thu Mar 17 2022 Dumitru Ceara <dceara@redhat.com> - 22.03.0-5
+- northd: Properly warn for NAT on LR with multiple gw ports.
+[Gerrit: 622d15d078178e854027358d5130690edbe75a4c]
+[Upstream: b8194738c99ee09ad6d4762a3c999e04d58d1a0f]
+
+* Fri Mar 11 2022 Mark Michelson <mmichels@redhat.com> - 22.03.0-4
+- Prepare for 22.03.1.
+[Gerrit: b3d273f73c4aa8d246e652f1fb505779d3828c5b]
+[Upstream: b3d273f73c4aa8d246e652f1fb505779d3828c5b]
+