|
Open vSwitch CI |
3f9b5c |
diff --git a/.ci/linux-prepare.sh b/.ci/linux-prepare.sh
|
|
Open vSwitch CI |
3f9b5c |
index c55125cf78..e4d2a187e0 100755
|
|
Open vSwitch CI |
3f9b5c |
--- a/.ci/linux-prepare.sh
|
|
Open vSwitch CI |
3f9b5c |
+++ b/.ci/linux-prepare.sh
|
|
Open vSwitch CI |
3f9b5c |
@@ -22,7 +22,6 @@ cd ..
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
pip3 install --disable-pip-version-check --user \
|
|
Open vSwitch CI |
3f9b5c |
flake8 hacking sphinx pyOpenSSL wheel setuptools
|
|
Open vSwitch CI |
3f9b5c |
-pip3 install --user --upgrade docutils
|
|
Open vSwitch CI |
3f9b5c |
pip3 install --user 'meson==0.47.1'
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if [ "$M32" ]; then
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/.cirrus.yml b/.cirrus.yml
|
|
Open vSwitch CI |
3f9b5c |
index 358f2ba256..480fea2421 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/.cirrus.yml
|
|
Open vSwitch CI |
3f9b5c |
+++ b/.cirrus.yml
|
|
Open vSwitch CI |
3f9b5c |
@@ -5,7 +5,7 @@ freebsd_build_task:
|
|
Open vSwitch CI |
3f9b5c |
image_family: freebsd-12-2-snap
|
|
Open vSwitch CI |
3f9b5c |
image_family: freebsd-11-4-snap
|
|
Open vSwitch CI |
3f9b5c |
cpu: 4
|
|
Open vSwitch CI |
3f9b5c |
- memory: 8G
|
|
Open vSwitch CI |
3f9b5c |
+ memory: 4G
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
env:
|
|
Open vSwitch CI |
3f9b5c |
DEPENDENCIES: automake libtool gmake gcc wget openssl python3
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
|
|
Open vSwitch CI |
3f9b5c |
index e2350c6d9d..7434ad18ec 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/.github/workflows/build-and-test.yml
|
|
Open vSwitch CI |
3f9b5c |
+++ b/.github/workflows/build-and-test.yml
|
|
Open vSwitch CI |
3f9b5c |
@@ -127,7 +127,7 @@ jobs:
|
|
Open vSwitch CI |
3f9b5c |
- name: set up python
|
|
Open vSwitch CI |
3f9b5c |
uses: actions/setup-python@v2
|
|
Open vSwitch CI |
3f9b5c |
with:
|
|
Open vSwitch CI |
3f9b5c |
- python-version: '3.x'
|
|
Open vSwitch CI |
3f9b5c |
+ python-version: '3.9'
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- name: create ci signature file for the dpdk cache key
|
|
Open vSwitch CI |
3f9b5c |
if: matrix.dpdk != '' || matrix.dpdk_shared != ''
|
|
Open vSwitch CI |
3f9b5c |
@@ -215,7 +215,7 @@ jobs:
|
|
Open vSwitch CI |
3f9b5c |
- name: set up python
|
|
Open vSwitch CI |
3f9b5c |
uses: actions/setup-python@v2
|
|
Open vSwitch CI |
3f9b5c |
with:
|
|
Open vSwitch CI |
3f9b5c |
- python-version: '3.x'
|
|
Open vSwitch CI |
3f9b5c |
+ python-version: '3.9'
|
|
Open vSwitch CI |
3f9b5c |
- name: install dependencies
|
|
Open vSwitch CI |
3f9b5c |
run: brew install automake libtool
|
|
Open vSwitch CI |
3f9b5c |
- name: prepare
|
|
|
110336 |
diff --git a/NEWS b/NEWS
|
|
Open vSwitch CI |
3f9b5c |
index 559a51ba3f..7a6de3da82 100644
|
|
|
110336 |
--- a/NEWS
|
|
|
110336 |
+++ b/NEWS
|
|
Open vSwitch CI |
3f9b5c |
@@ -1,3 +1,10 @@
|
|
Open vSwitch CI |
3f9b5c |
+v2.16.2 - xx xxx xxxx
|
|
|
110336 |
+---------------------
|
|
|
110336 |
+
|
|
Open vSwitch CI |
3f9b5c |
+v2.16.1 - 21 Oct 2021
|
|
Open vSwitch CI |
3f9b5c |
+---------------------
|
|
Open vSwitch CI |
3f9b5c |
+ - Bug fixes
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
|
110336 |
v2.16.0 - 16 Aug 2021
|
|
|
110336 |
---------------------
|
|
|
110336 |
- Removed support for 1024-bit Diffie-Hellman key exchange, which is now
|
|
|
110336 |
diff --git a/configure.ac b/configure.ac
|
|
Open vSwitch CI |
3f9b5c |
index 16b32be965..64c26828f2 100644
|
|
|
110336 |
--- a/configure.ac
|
|
|
110336 |
+++ b/configure.ac
|
|
|
110336 |
@@ -13,7 +13,7 @@
|
|
|
110336 |
# limitations under the License.
|
|
|
110336 |
|
|
|
110336 |
AC_PREREQ(2.63)
|
|
|
110336 |
-AC_INIT(openvswitch, 2.16.0, bugs@openvswitch.org)
|
|
Open vSwitch CI |
3f9b5c |
+AC_INIT(openvswitch, 2.16.2, bugs@openvswitch.org)
|
|
|
110336 |
AC_CONFIG_SRCDIR([datapath/datapath.c])
|
|
|
110336 |
AC_CONFIG_MACRO_DIR([m4])
|
|
|
110336 |
AC_CONFIG_AUX_DIR([build-aux])
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
|
|
Open vSwitch CI |
3f9b5c |
index e130c2f966..0c18c62548 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/datapath-windows/ovsext/Actions.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/datapath-windows/ovsext/Actions.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -1112,9 +1112,9 @@ OvsPopFieldInPacketBuf(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
* should split the function and refactor. */
|
|
Open vSwitch CI |
3f9b5c |
if (!bufferData) {
|
|
Open vSwitch CI |
3f9b5c |
EthHdr *ethHdr = (EthHdr *)bufferStart;
|
|
Open vSwitch CI |
3f9b5c |
- /* If the frame is not VLAN make it a no op */
|
|
Open vSwitch CI |
3f9b5c |
if (ethHdr->Type != ETH_TYPE_802_1PQ_NBO) {
|
|
Open vSwitch CI |
3f9b5c |
- return NDIS_STATUS_SUCCESS;
|
|
Open vSwitch CI |
3f9b5c |
+ OVS_LOG_ERROR("Invalid ethHdr type %u, nbl %p", ethHdr->Type, ovsFwdCtx->curNbl);
|
|
Open vSwitch CI |
3f9b5c |
+ return NDIS_STATUS_INVALID_PACKET;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
RtlMoveMemory(bufferStart + shiftLength, bufferStart, shiftOffset);
|
|
Open vSwitch CI |
3f9b5c |
@@ -1137,6 +1137,9 @@ OvsPopFieldInPacketBuf(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
static __inline NDIS_STATUS
|
|
Open vSwitch CI |
3f9b5c |
OvsPopVlanInPktBuf(OvsForwardingContext *ovsFwdCtx)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
+ NDIS_STATUS status;
|
|
Open vSwitch CI |
3f9b5c |
+ OVS_PACKET_HDR_INFO* layers = &ovsFwdCtx->layers;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/*
|
|
Open vSwitch CI |
3f9b5c |
* Declare a dummy vlanTag structure since we need to compute the size
|
|
Open vSwitch CI |
3f9b5c |
* of shiftLength. The NDIS one is a unionized structure.
|
|
Open vSwitch CI |
3f9b5c |
@@ -1145,7 +1148,15 @@ OvsPopVlanInPktBuf(OvsForwardingContext *ovsFwdCtx)
|
|
Open vSwitch CI |
3f9b5c |
UINT32 shiftLength = sizeof(vlanTag.TagHeader);
|
|
Open vSwitch CI |
3f9b5c |
UINT32 shiftOffset = sizeof(DL_EUI48) + sizeof(DL_EUI48);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- return OvsPopFieldInPacketBuf(ovsFwdCtx, shiftOffset, shiftLength, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ status = OvsPopFieldInPacketBuf(ovsFwdCtx, shiftOffset, shiftLength,
|
|
Open vSwitch CI |
3f9b5c |
+ NULL);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ if (status == NDIS_STATUS_SUCCESS) {
|
|
Open vSwitch CI |
3f9b5c |
+ layers->l3Offset -= (UINT16) shiftLength;
|
|
Open vSwitch CI |
3f9b5c |
+ layers->l4Offset -= (UINT16) shiftLength;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ return status;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -1516,6 +1527,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
csumInfo.Value = NET_BUFFER_LIST_INFO(ovsFwdCtx->curNbl,
|
|
Open vSwitch CI |
3f9b5c |
TcpIpChecksumNetBufferListInfo);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/*
|
|
Open vSwitch CI |
3f9b5c |
* Adjust the IP header inline as dictated by the action, and also update
|
|
Open vSwitch CI |
3f9b5c |
* the IP and the TCP checksum for the data modified.
|
|
Open vSwitch CI |
3f9b5c |
@@ -1524,6 +1536,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
* ChecksumUpdate32(). Ignoring this for now, since for the most common
|
|
Open vSwitch CI |
3f9b5c |
* case, we only update the TTL.
|
|
Open vSwitch CI |
3f9b5c |
*/
|
|
Open vSwitch CI |
3f9b5c |
+ /*Only tx direction the checksum value will be reset to be PseudoChecksum*/
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (isSource) {
|
|
Open vSwitch CI |
3f9b5c |
addrField = &ipHdr->saddr;
|
|
Open vSwitch CI |
3f9b5c |
@@ -1540,7 +1553,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
((BOOLEAN)csumInfo.Receive.UdpChecksumSucceeded ||
|
|
Open vSwitch CI |
3f9b5c |
(BOOLEAN)csumInfo.Receive.UdpChecksumFailed);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- if (l4Offload) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (isTx && l4Offload) {
|
|
Open vSwitch CI |
3f9b5c |
*checkField = IPPseudoChecksum(&newAddr, &ipHdr->daddr,
|
|
Open vSwitch CI |
3f9b5c |
tcpHdr ? IPPROTO_TCP : IPPROTO_UDP,
|
|
Open vSwitch CI |
3f9b5c |
ntohs(ipHdr->tot_len) - ipHdr->ihl * 4);
|
|
Open vSwitch CI |
3f9b5c |
@@ -1561,7 +1574,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
(BOOLEAN)csumInfo.Receive.UdpChecksumFailed);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- if (l4Offload) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (isTx && l4Offload) {
|
|
Open vSwitch CI |
3f9b5c |
*checkField = IPPseudoChecksum(&ipHdr->saddr, &newAddr,
|
|
Open vSwitch CI |
3f9b5c |
tcpHdr ? IPPROTO_TCP : IPPROTO_UDP,
|
|
Open vSwitch CI |
3f9b5c |
ntohs(ipHdr->tot_len) - ipHdr->ihl * 4);
|
|
Open vSwitch CI |
3f9b5c |
@@ -1570,7 +1583,7 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (*addrField != newAddr) {
|
|
Open vSwitch CI |
3f9b5c |
UINT32 oldAddr = *addrField;
|
|
Open vSwitch CI |
3f9b5c |
- if (checkField && *checkField != 0 && !l4Offload) {
|
|
Open vSwitch CI |
3f9b5c |
+ if ((checkField && *checkField != 0) && (!l4Offload || !isTx)) {
|
|
Open vSwitch CI |
3f9b5c |
/* Recompute total checksum. */
|
|
Open vSwitch CI |
3f9b5c |
*checkField = ChecksumUpdate32(*checkField, oldAddr,
|
|
Open vSwitch CI |
3f9b5c |
newAddr);
|
|
Open vSwitch CI |
3f9b5c |
@@ -1579,11 +1592,12 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
ipHdr->check = ChecksumUpdate32(ipHdr->check, oldAddr,
|
|
Open vSwitch CI |
3f9b5c |
newAddr);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
*addrField = newAddr;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (portField && *portField != newPort) {
|
|
Open vSwitch CI |
3f9b5c |
- if (checkField && !l4Offload) {
|
|
Open vSwitch CI |
3f9b5c |
+ if ((checkField) && (!l4Offload || !isTx)) {
|
|
Open vSwitch CI |
3f9b5c |
/* Recompute total checksum. */
|
|
Open vSwitch CI |
3f9b5c |
*checkField = ChecksumUpdate16(*checkField, *portField,
|
|
Open vSwitch CI |
3f9b5c |
newPort);
|
|
Open vSwitch CI |
3f9b5c |
@@ -1792,9 +1806,11 @@ OvsExecuteRecirc(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (newNbl) {
|
|
Open vSwitch CI |
3f9b5c |
- deferredAction = OvsAddDeferredActions(newNbl, key, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ deferredAction = OvsAddDeferredActions(newNbl, key, &(ovsFwdCtx->layers),
|
|
Open vSwitch CI |
3f9b5c |
+ NULL);
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
- deferredAction = OvsAddDeferredActions(ovsFwdCtx->curNbl, key, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ deferredAction = OvsAddDeferredActions(ovsFwdCtx->curNbl, key,
|
|
Open vSwitch CI |
3f9b5c |
+ &(ovsFwdCtx->layers), NULL);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (deferredAction) {
|
|
Open vSwitch CI |
3f9b5c |
@@ -1964,7 +1980,7 @@ OvsExecuteSampleAction(OvsForwardingContext *ovsFwdCtx,
|
|
Open vSwitch CI |
3f9b5c |
return STATUS_SUCCESS;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- if (!OvsAddDeferredActions(newNbl, key, a)) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!OvsAddDeferredActions(newNbl, key, &(ovsFwdCtx->layers), a)) {
|
|
Open vSwitch CI |
3f9b5c |
OVS_LOG_INFO(
|
|
Open vSwitch CI |
3f9b5c |
"Deferred actions limit reached, dropping sample action.");
|
|
Open vSwitch CI |
3f9b5c |
OvsCompleteNBL(ovsFwdCtx->switchContext, newNbl, TRUE);
|
|
Open vSwitch CI |
3f9b5c |
@@ -2100,6 +2116,7 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
|
|
Open vSwitch CI |
3f9b5c |
*/
|
|
Open vSwitch CI |
3f9b5c |
status = OvsPopVlanInPktBuf(&ovsFwdCtx);
|
|
Open vSwitch CI |
3f9b5c |
if (status != NDIS_STATUS_SUCCESS) {
|
|
Open vSwitch CI |
3f9b5c |
+ OVS_LOG_ERROR("OVS-pop vlan action failed status = %lu", status);
|
|
Open vSwitch CI |
3f9b5c |
dropReason = L"OVS-pop vlan action failed";
|
|
Open vSwitch CI |
3f9b5c |
goto dropit;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
@@ -2349,7 +2366,7 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (status == STATUS_SUCCESS) {
|
|
Open vSwitch CI |
3f9b5c |
status = OvsProcessDeferredActions(switchContext, completionList,
|
|
Open vSwitch CI |
3f9b5c |
- portNo, sendFlags, layers);
|
|
Open vSwitch CI |
3f9b5c |
+ portNo, sendFlags, NULL);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
return status;
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/datapath-windows/ovsext/Recirc.c b/datapath-windows/ovsext/Recirc.c
|
|
Open vSwitch CI |
3f9b5c |
index 2febf060dd..a32b75352b 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/datapath-windows/ovsext/Recirc.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/datapath-windows/ovsext/Recirc.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -277,16 +277,23 @@ OvsDeferredActionsQueuePush(POVS_DEFERRED_ACTION_QUEUE queue)
|
|
Open vSwitch CI |
3f9b5c |
POVS_DEFERRED_ACTION
|
|
Open vSwitch CI |
3f9b5c |
OvsAddDeferredActions(PNET_BUFFER_LIST nbl,
|
|
Open vSwitch CI |
3f9b5c |
OvsFlowKey *key,
|
|
Open vSwitch CI |
3f9b5c |
+ POVS_PACKET_HDR_INFO layers,
|
|
Open vSwitch CI |
3f9b5c |
const PNL_ATTR actions)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
POVS_DEFERRED_ACTION_QUEUE queue = OvsDeferredActionsQueueGet();
|
|
Open vSwitch CI |
3f9b5c |
POVS_DEFERRED_ACTION deferredAction = NULL;
|
|
Open vSwitch CI |
3f9b5c |
+ OVS_PACKET_HDR_INFO layersInit = { 0 };
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
deferredAction = OvsDeferredActionsQueuePush(queue);
|
|
Open vSwitch CI |
3f9b5c |
if (deferredAction) {
|
|
Open vSwitch CI |
3f9b5c |
deferredAction->nbl = nbl;
|
|
Open vSwitch CI |
3f9b5c |
deferredAction->actions = actions;
|
|
Open vSwitch CI |
3f9b5c |
deferredAction->key = *key;
|
|
Open vSwitch CI |
3f9b5c |
+ if (layers) {
|
|
Open vSwitch CI |
3f9b5c |
+ deferredAction->layers = *layers;
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ deferredAction->layers = layersInit;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
return deferredAction;
|
|
Open vSwitch CI |
3f9b5c |
@@ -309,9 +316,16 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
|
|
Open vSwitch CI |
3f9b5c |
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
|
|
Open vSwitch CI |
3f9b5c |
POVS_DEFERRED_ACTION_QUEUE queue = OvsDeferredActionsQueueGet();
|
|
Open vSwitch CI |
3f9b5c |
POVS_DEFERRED_ACTION deferredAction = NULL;
|
|
Open vSwitch CI |
3f9b5c |
+ POVS_PACKET_HDR_INFO layersDeferred = NULL;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* Process all deferred actions. */
|
|
Open vSwitch CI |
3f9b5c |
while ((deferredAction = OvsDeferredActionsQueuePop(queue)) != NULL) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (layers) {
|
|
Open vSwitch CI |
3f9b5c |
+ layersDeferred = layers;
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ layersDeferred = &(deferredAction->layers);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
if (deferredAction->actions) {
|
|
Open vSwitch CI |
3f9b5c |
status = OvsDoExecuteActions(switchContext,
|
|
Open vSwitch CI |
3f9b5c |
completionList,
|
|
Open vSwitch CI |
3f9b5c |
@@ -319,7 +333,7 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
|
|
Open vSwitch CI |
3f9b5c |
portNo,
|
|
Open vSwitch CI |
3f9b5c |
sendFlags,
|
|
Open vSwitch CI |
3f9b5c |
&deferredAction->key, NULL,
|
|
Open vSwitch CI |
3f9b5c |
- layers, deferredAction->actions,
|
|
Open vSwitch CI |
3f9b5c |
+ layersDeferred, deferredAction->actions,
|
|
Open vSwitch CI |
3f9b5c |
NlAttrGetSize(deferredAction->actions));
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
status = OvsDoRecirc(switchContext,
|
|
Open vSwitch CI |
3f9b5c |
@@ -327,7 +341,7 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
|
|
Open vSwitch CI |
3f9b5c |
deferredAction->nbl,
|
|
Open vSwitch CI |
3f9b5c |
&deferredAction->key,
|
|
Open vSwitch CI |
3f9b5c |
portNo,
|
|
Open vSwitch CI |
3f9b5c |
- layers);
|
|
Open vSwitch CI |
3f9b5c |
+ layersDeferred);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/datapath-windows/ovsext/Recirc.h b/datapath-windows/ovsext/Recirc.h
|
|
Open vSwitch CI |
3f9b5c |
index 2b314ce274..74130a4600 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/datapath-windows/ovsext/Recirc.h
|
|
Open vSwitch CI |
3f9b5c |
+++ b/datapath-windows/ovsext/Recirc.h
|
|
Open vSwitch CI |
3f9b5c |
@@ -18,6 +18,7 @@
|
|
Open vSwitch CI |
3f9b5c |
#define __RECIRC_H_ 1
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
#include "Actions.h"
|
|
Open vSwitch CI |
3f9b5c |
+#include "NetProto.h"
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
#define DEFERRED_ACTION_QUEUE_SIZE 10
|
|
Open vSwitch CI |
3f9b5c |
#define DEFERRED_ACTION_EXEC_LEVEL 4
|
|
Open vSwitch CI |
3f9b5c |
@@ -26,6 +27,7 @@ typedef struct _OVS_DEFERRED_ACTION {
|
|
Open vSwitch CI |
3f9b5c |
PNET_BUFFER_LIST nbl;
|
|
Open vSwitch CI |
3f9b5c |
PNL_ATTR actions;
|
|
Open vSwitch CI |
3f9b5c |
OvsFlowKey key;
|
|
Open vSwitch CI |
3f9b5c |
+ OVS_PACKET_HDR_INFO layers;
|
|
Open vSwitch CI |
3f9b5c |
} OVS_DEFERRED_ACTION, *POVS_DEFERRED_ACTION;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/*
|
|
Open vSwitch CI |
3f9b5c |
@@ -52,6 +54,7 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
|
|
Open vSwitch CI |
3f9b5c |
POVS_DEFERRED_ACTION
|
|
Open vSwitch CI |
3f9b5c |
OvsAddDeferredActions(PNET_BUFFER_LIST packet,
|
|
Open vSwitch CI |
3f9b5c |
OvsFlowKey *key,
|
|
Open vSwitch CI |
3f9b5c |
+ POVS_PACKET_HDR_INFO layers,
|
|
Open vSwitch CI |
3f9b5c |
const PNL_ATTR actions);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/*
|
|
|
110336 |
diff --git a/debian/changelog b/debian/changelog
|
|
Open vSwitch CI |
3f9b5c |
index 239d210b96..a0838ea3d7 100644
|
|
|
110336 |
--- a/debian/changelog
|
|
|
110336 |
+++ b/debian/changelog
|
|
Open vSwitch CI |
3f9b5c |
@@ -1,3 +1,15 @@
|
|
Open vSwitch CI |
3f9b5c |
+openvswitch (2.16.2-1) unstable; urgency=low
|
|
Open vSwitch CI |
3f9b5c |
+ [ Open vSwitch team ]
|
|
Open vSwitch CI |
3f9b5c |
+ * New upstream version
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ -- Open vSwitch team <dev@openvswitch.org> Thu, 21 Oct 2021 23:58:12 +0200
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
|
110336 |
+openvswitch (2.16.1-1) unstable; urgency=low
|
|
|
110336 |
+ [ Open vSwitch team ]
|
|
|
110336 |
+ * New upstream version
|
|
|
110336 |
+
|
|
Open vSwitch CI |
3f9b5c |
+ -- Open vSwitch team <dev@openvswitch.org> Thu, 21 Oct 2021 23:58:12 +0200
|
|
|
110336 |
+
|
|
|
110336 |
openvswitch (2.16.0-1) unstable; urgency=low
|
|
|
110336 |
|
|
|
110336 |
* New upstream version
|
|
|
110336 |
diff --git a/include/openvswitch/json.h b/include/openvswitch/json.h
|
|
|
110336 |
index 73b562e03d..0831a9cee1 100644
|
|
|
110336 |
--- a/include/openvswitch/json.h
|
|
|
110336 |
+++ b/include/openvswitch/json.h
|
|
|
110336 |
@@ -50,7 +50,9 @@ enum json_type {
|
|
|
110336 |
JSON_INTEGER, /* 123. */
|
|
|
110336 |
JSON_REAL, /* 123.456. */
|
|
|
110336 |
JSON_STRING, /* "..." */
|
|
|
110336 |
- JSON_N_TYPES
|
|
|
110336 |
+ JSON_N_TYPES,
|
|
|
110336 |
+ JSON_SERIALIZED_OBJECT, /* Internal type to hold serialized version of
|
|
|
110336 |
+ * data of other types. */
|
|
|
110336 |
};
|
|
|
110336 |
|
|
|
110336 |
const char *json_type_to_string(enum json_type);
|
|
|
110336 |
@@ -70,7 +72,7 @@ struct json {
|
|
|
110336 |
struct json_array array;
|
|
|
110336 |
long long int integer;
|
|
|
110336 |
double real;
|
|
|
110336 |
- char *string;
|
|
|
110336 |
+ char *string; /* JSON_STRING or JSON_SERIALIZED_OBJECT. */
|
|
|
110336 |
};
|
|
|
110336 |
};
|
|
|
110336 |
|
|
|
110336 |
@@ -78,6 +80,7 @@ struct json *json_null_create(void);
|
|
|
110336 |
struct json *json_boolean_create(bool);
|
|
|
110336 |
struct json *json_string_create(const char *);
|
|
|
110336 |
struct json *json_string_create_nocopy(char *);
|
|
|
110336 |
+struct json *json_serialized_object_create(const struct json *);
|
|
|
110336 |
struct json *json_integer_create(long long int);
|
|
|
110336 |
struct json *json_real_create(double);
|
|
|
110336 |
|
|
|
110336 |
@@ -99,6 +102,7 @@ void json_object_put_format(struct json *,
|
|
|
110336 |
OVS_PRINTF_FORMAT(3, 4);
|
|
|
110336 |
|
|
|
110336 |
const char *json_string(const struct json *);
|
|
|
110336 |
+const char *json_serialized_object(const struct json *);
|
|
|
110336 |
struct json_array *json_array(const struct json *);
|
|
|
110336 |
struct shash *json_object(const struct json *);
|
|
|
110336 |
bool json_boolean(const struct json *);
|
|
|
110336 |
@@ -125,6 +129,7 @@ struct json *json_parser_finish(struct json_parser *);
|
|
|
110336 |
void json_parser_abort(struct json_parser *);
|
|
|
110336 |
|
|
|
110336 |
struct json *json_from_string(const char *string);
|
|
|
110336 |
+struct json *json_from_serialized_object(const struct json *);
|
|
|
110336 |
struct json *json_from_file(const char *file_name);
|
|
|
110336 |
struct json *json_from_stream(FILE *stream);
|
|
|
110336 |
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
|
|
Open vSwitch CI |
3f9b5c |
index 95e52e3587..045dce8f5f 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/include/openvswitch/meta-flow.h
|
|
Open vSwitch CI |
3f9b5c |
+++ b/include/openvswitch/meta-flow.h
|
|
Open vSwitch CI |
3f9b5c |
@@ -2305,6 +2305,7 @@ void mf_set_flow_value_masked(const struct mf_field *,
|
|
Open vSwitch CI |
3f9b5c |
const union mf_value *mask,
|
|
Open vSwitch CI |
3f9b5c |
struct flow *);
|
|
Open vSwitch CI |
3f9b5c |
bool mf_is_tun_metadata(const struct mf_field *);
|
|
Open vSwitch CI |
3f9b5c |
+bool mf_is_frozen_metadata(const struct mf_field *);
|
|
Open vSwitch CI |
3f9b5c |
bool mf_is_pipeline_field(const struct mf_field *);
|
|
Open vSwitch CI |
3f9b5c |
bool mf_is_set(const struct mf_field *, const struct flow *);
|
|
Open vSwitch CI |
3f9b5c |
void mf_mask_field(const struct mf_field *, struct flow_wildcards *);
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/db-ctl-base.c b/lib/db-ctl-base.c
|
|
Open vSwitch CI |
3f9b5c |
index 77cc76a9f6..7074561588 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/db-ctl-base.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/db-ctl-base.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -247,15 +247,15 @@ record_id_equals(const union ovsdb_atom *name, enum ovsdb_atomic_type type,
|
|
Open vSwitch CI |
3f9b5c |
const char *record_id)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
if (type == OVSDB_TYPE_STRING) {
|
|
Open vSwitch CI |
3f9b5c |
- if (!strcmp(name->string, record_id)) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!strcmp(name->s->string, record_id)) {
|
|
Open vSwitch CI |
3f9b5c |
return true;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
struct uuid uuid;
|
|
Open vSwitch CI |
3f9b5c |
size_t len = strlen(record_id);
|
|
Open vSwitch CI |
3f9b5c |
if (len >= 4
|
|
Open vSwitch CI |
3f9b5c |
- && uuid_from_string(&uuid, name->string)
|
|
Open vSwitch CI |
3f9b5c |
- && !strncmp(name->string, record_id, len)) {
|
|
Open vSwitch CI |
3f9b5c |
+ && uuid_from_string(&uuid, name->s->string)
|
|
Open vSwitch CI |
3f9b5c |
+ && !strncmp(name->s->string, record_id, len)) {
|
|
Open vSwitch CI |
3f9b5c |
return true;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -314,15 +314,19 @@ get_row_by_id(struct ctl_context *ctx,
|
|
Open vSwitch CI |
3f9b5c |
row, id->name_column, key, value);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* Extract the name from the column. */
|
|
Open vSwitch CI |
3f9b5c |
- const union ovsdb_atom *name;
|
|
Open vSwitch CI |
3f9b5c |
+ const union ovsdb_atom *name = NULL;
|
|
Open vSwitch CI |
3f9b5c |
if (!id->key) {
|
|
Open vSwitch CI |
3f9b5c |
name = datum->n == 1 ? &datum->keys[0] : NULL;
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
- const union ovsdb_atom key_atom
|
|
Open vSwitch CI |
3f9b5c |
- = { .string = CONST_CAST(char *, id->key) };
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int i = ovsdb_datum_find_key(datum, &key_atom,
|
|
Open vSwitch CI |
3f9b5c |
- OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
- name = i == UINT_MAX ? NULL : &datum->values[i];
|
|
Open vSwitch CI |
3f9b5c |
+ union ovsdb_atom key_atom = {
|
|
Open vSwitch CI |
3f9b5c |
+ .s = ovsdb_atom_string_create(CONST_CAST(char *, id->key)) };
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int i;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ if (ovsdb_datum_find_key(datum, &key_atom,
|
|
Open vSwitch CI |
3f9b5c |
+ OVSDB_TYPE_STRING, &i)) {
|
|
Open vSwitch CI |
3f9b5c |
+ name = &datum->values[i];
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_destroy(&key_atom, OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
if (!name) {
|
|
Open vSwitch CI |
3f9b5c |
continue;
|
|
Open vSwitch CI |
3f9b5c |
@@ -819,14 +823,14 @@ check_condition(const struct ovsdb_idl_table_class *table,
|
|
Open vSwitch CI |
3f9b5c |
goto out;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- idx = ovsdb_datum_find_key(have_datum,
|
|
Open vSwitch CI |
3f9b5c |
- &want_key, column->type.key.type);
|
|
Open vSwitch CI |
3f9b5c |
- if (idx == UINT_MAX && !is_set_operator(operator)) {
|
|
Open vSwitch CI |
3f9b5c |
+ bool found = ovsdb_datum_find_key(have_datum, &want_key,
|
|
Open vSwitch CI |
3f9b5c |
+ column->type.key.type, &idx);
|
|
Open vSwitch CI |
3f9b5c |
+ if (!found && !is_set_operator(operator)) {
|
|
Open vSwitch CI |
3f9b5c |
retval = false;
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_datum a;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- if (idx != UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (found) {
|
|
Open vSwitch CI |
3f9b5c |
a.n = 1;
|
|
Open vSwitch CI |
3f9b5c |
a.keys = &have_datum->values[idx];
|
|
Open vSwitch CI |
3f9b5c |
a.values = NULL;
|
|
Open vSwitch CI |
3f9b5c |
@@ -992,9 +996,8 @@ cmd_get(struct ctl_context *ctx)
|
|
Open vSwitch CI |
3f9b5c |
return;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- idx = ovsdb_datum_find_key(datum, &key,
|
|
Open vSwitch CI |
3f9b5c |
- column->type.key.type);
|
|
Open vSwitch CI |
3f9b5c |
- if (idx == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_find_key(datum, &key,
|
|
Open vSwitch CI |
3f9b5c |
+ column->type.key.type, &idx)) {
|
|
Open vSwitch CI |
3f9b5c |
if (must_exist) {
|
|
Open vSwitch CI |
3f9b5c |
ctl_error(
|
|
Open vSwitch CI |
3f9b5c |
ctx, "no key \"%s\" in %s record \"%s\" column %s",
|
|
Open vSwitch CI |
3f9b5c |
@@ -1375,7 +1378,7 @@ set_column(const struct ovsdb_idl_table_class *table,
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_atom_destroy(&value, column->type.value.type);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_union(&datum, ovsdb_idl_read(row, column),
|
|
Open vSwitch CI |
3f9b5c |
- &column->type, false);
|
|
Open vSwitch CI |
3f9b5c |
+ &column->type);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_verify(row, column);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_write(row, column, &datum);
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
@@ -1514,7 +1517,7 @@ cmd_add(struct ctl_context *ctx)
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_destroy(&old, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
return;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_union(&old, &add, type, false);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_union(&old, &add, type);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_destroy(&add, type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
if (old.n > type->n_max) {
|
|
|
110336 |
diff --git a/lib/dp-packet.h b/lib/dp-packet.h
|
|
|
110336 |
index 08d93c2779..3dc582fbfd 100644
|
|
|
110336 |
--- a/lib/dp-packet.h
|
|
|
110336 |
+++ b/lib/dp-packet.h
|
|
|
110336 |
@@ -199,6 +199,7 @@ struct dp_packet *dp_packet_clone_data_with_headroom(const void *, size_t,
|
|
|
110336 |
void dp_packet_resize(struct dp_packet *b, size_t new_headroom,
|
|
|
110336 |
size_t new_tailroom);
|
|
|
110336 |
static inline void dp_packet_delete(struct dp_packet *);
|
|
|
110336 |
+static inline void dp_packet_swap(struct dp_packet *, struct dp_packet *);
|
|
|
110336 |
|
|
|
110336 |
static inline void *dp_packet_at(const struct dp_packet *, size_t offset,
|
|
|
110336 |
size_t size);
|
|
|
110336 |
@@ -256,6 +257,18 @@ dp_packet_delete(struct dp_packet *b)
|
|
|
110336 |
}
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
+/* Swaps content of two packets. */
|
|
|
110336 |
+static inline void
|
|
|
110336 |
+dp_packet_swap(struct dp_packet *a, struct dp_packet *b)
|
|
|
110336 |
+{
|
|
|
110336 |
+ ovs_assert(a->source == DPBUF_MALLOC || a->source == DPBUF_STUB);
|
|
|
110336 |
+ ovs_assert(b->source == DPBUF_MALLOC || b->source == DPBUF_STUB);
|
|
|
110336 |
+ struct dp_packet c = *a;
|
|
|
110336 |
+
|
|
|
110336 |
+ *a = *b;
|
|
|
110336 |
+ *b = c;
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
/* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to
|
|
|
110336 |
* byte 'offset'. Otherwise, returns a null pointer. */
|
|
|
110336 |
static inline void *
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/dpdk-stub.c b/lib/dpdk-stub.c
|
|
Open vSwitch CI |
3f9b5c |
index b7d577870d..fe24f9abdf 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/dpdk-stub.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/dpdk-stub.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -83,7 +83,7 @@ bool
|
|
Open vSwitch CI |
3f9b5c |
dpdk_get_cpu_has_isa(const char *arch OVS_UNUSED,
|
|
Open vSwitch CI |
3f9b5c |
const char *feature OVS_UNUSED)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
- VLOG_ERR_ONCE("DPDK not supported in this version of Open vSwitch, "
|
|
Open vSwitch CI |
3f9b5c |
+ VLOG_DBG_ONCE("DPDK not supported in this version of Open vSwitch, "
|
|
Open vSwitch CI |
3f9b5c |
"cannot use CPU flag based optimizations");
|
|
Open vSwitch CI |
3f9b5c |
return false;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/dpif-netdev-private-dfc.h b/lib/dpif-netdev-private-dfc.h
|
|
Open vSwitch CI |
3f9b5c |
index 92092ebec9..3dfc91f0fe 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/dpif-netdev-private-dfc.h
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/dpif-netdev-private-dfc.h
|
|
Open vSwitch CI |
3f9b5c |
@@ -59,7 +59,8 @@ extern "C" {
|
|
Open vSwitch CI |
3f9b5c |
* Thread-safety
|
|
Open vSwitch CI |
3f9b5c |
* =============
|
|
Open vSwitch CI |
3f9b5c |
*
|
|
Open vSwitch CI |
3f9b5c |
- * Each pmd_thread has its own private exact match cache.
|
|
Open vSwitch CI |
3f9b5c |
+ * Each pmd_thread has its own private exact match cache and signature match
|
|
Open vSwitch CI |
3f9b5c |
+ * cache.
|
|
Open vSwitch CI |
3f9b5c |
* If dp_netdev_input is not called from a pmd thread, a mutex is used.
|
|
Open vSwitch CI |
3f9b5c |
*/
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/dpif-netdev-private-thread.h b/lib/dpif-netdev-private-thread.h
|
|
Open vSwitch CI |
3f9b5c |
index a782d9678a..ac4885538c 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/dpif-netdev-private-thread.h
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/dpif-netdev-private-thread.h
|
|
Open vSwitch CI |
3f9b5c |
@@ -78,10 +78,10 @@ struct dp_netdev_pmd_thread {
|
|
Open vSwitch CI |
3f9b5c |
struct ovs_refcount ref_cnt; /* Every reference must be refcount'ed. */
|
|
Open vSwitch CI |
3f9b5c |
struct cmap_node node; /* In 'dp->poll_threads'. */
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- /* Per thread exact-match cache. Note, the instance for cpu core
|
|
Open vSwitch CI |
3f9b5c |
- * NON_PMD_CORE_ID can be accessed by multiple threads, and thusly
|
|
Open vSwitch CI |
3f9b5c |
- * need to be protected by 'non_pmd_mutex'. Every other instance
|
|
Open vSwitch CI |
3f9b5c |
- * will only be accessed by its own pmd thread. */
|
|
Open vSwitch CI |
3f9b5c |
+ /* Per thread exact match cache and signature match cache. Note, the
|
|
Open vSwitch CI |
3f9b5c |
+ * instance for cpu core NON_PMD_CORE_ID can be accessed by multiple
|
|
Open vSwitch CI |
3f9b5c |
+ * threads, and thusly need to be protected by 'non_pmd_mutex'. Every
|
|
Open vSwitch CI |
3f9b5c |
+ * other instance will only be accessed by its own pmd thread. */
|
|
Open vSwitch CI |
3f9b5c |
OVS_ALIGNED_VAR(CACHE_LINE_SIZE) struct dfc_cache flow_cache;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* Flow-Table and classifiers
|
|
|
110336 |
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
|
|
Open vSwitch CI |
3f9b5c |
index bddce75b63..d6bee2a5a9 100644
|
|
|
110336 |
--- a/lib/dpif-netdev.c
|
|
|
110336 |
+++ b/lib/dpif-netdev.c
|
|
|
110336 |
@@ -4061,7 +4061,10 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
|
|
|
110336 |
flow_hash_5tuple(execute->flow, 0));
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
- dp_packet_batch_init_packet(&pp, execute->packet);
|
|
|
110336 |
+ /* Making a copy because the packet might be stolen during the execution
|
|
|
110336 |
+ * and caller might still need it. */
|
|
|
110336 |
+ struct dp_packet *packet_clone = dp_packet_clone(execute->packet);
|
|
|
110336 |
+ dp_packet_batch_init_packet(&pp, packet_clone);
|
|
|
110336 |
dp_netdev_execute_actions(pmd, &pp, false, execute->flow,
|
|
|
110336 |
execute->actions, execute->actions_len);
|
|
|
110336 |
dp_netdev_pmd_flush_output_packets(pmd, true);
|
|
Open vSwitch CI |
3f9b5c |
@@ -4071,6 +4074,24 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
|
|
|
110336 |
dp_netdev_pmd_unref(pmd);
|
|
|
110336 |
}
|
|
|
110336 |
|
|
Open vSwitch CI |
3f9b5c |
+ if (dp_packet_batch_size(&pp) == 1) {
|
|
|
110336 |
+ /* Packet wasn't dropped during the execution. Swapping content with
|
|
|
110336 |
+ * the original packet, because the caller might expect actions to
|
|
Open vSwitch CI |
3f9b5c |
+ * modify it. Uisng the packet from a batch instead of 'packet_clone'
|
|
Open vSwitch CI |
3f9b5c |
+ * because it maybe stolen and replaced by other packet, e.g. by
|
|
Open vSwitch CI |
3f9b5c |
+ * the fragmentation engine. */
|
|
Open vSwitch CI |
3f9b5c |
+ dp_packet_swap(execute->packet, pp.packets[0]);
|
|
Open vSwitch CI |
3f9b5c |
+ dp_packet_delete_batch(&pp, true);
|
|
Open vSwitch CI |
3f9b5c |
+ } else if (dp_packet_batch_size(&pp)) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* FIXME: We have more packets than expected. Likely, we got IP
|
|
Open vSwitch CI |
3f9b5c |
+ * fragments of the reassembled packet. Dropping them here as we have
|
|
Open vSwitch CI |
3f9b5c |
+ * no way to get them to the caller. It might be that all the required
|
|
Open vSwitch CI |
3f9b5c |
+ * actions with them are already executed, but it also might not be a
|
|
Open vSwitch CI |
3f9b5c |
+ * case, e.g. if dpif_netdev_execute() called to execute a single
|
|
Open vSwitch CI |
3f9b5c |
+ * tunnel push. */
|
|
|
110336 |
+ dp_packet_delete_batch(&pp, true);
|
|
|
110336 |
+ }
|
|
|
110336 |
+
|
|
|
110336 |
return 0;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
|
|
Open vSwitch CI |
3f9b5c |
index 34fc042373..5f4b60c5a6 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/dpif-netlink.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/dpif-netlink.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -84,6 +84,8 @@ enum { MAX_PORTS = USHRT_MAX };
|
|
Open vSwitch CI |
3f9b5c |
#define EPOLLEXCLUSIVE (1u << 28)
|
|
Open vSwitch CI |
3f9b5c |
#endif
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+#define OVS_DP_F_UNSUPPORTED (1 << 31);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/* This PID is not used by the kernel datapath when using dispatch per CPU,
|
|
Open vSwitch CI |
3f9b5c |
* but it is required to be set (not zero). */
|
|
Open vSwitch CI |
3f9b5c |
#define DPIF_NETLINK_PER_CPU_PID UINT32_MAX
|
|
Open vSwitch CI |
3f9b5c |
@@ -382,36 +384,62 @@ dpif_netlink_open(const struct dpif_class *class OVS_UNUSED, const char *name,
|
|
Open vSwitch CI |
3f9b5c |
dp_request.cmd = OVS_DP_CMD_SET;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- /* The Open vSwitch kernel module has two modes for dispatching upcalls:
|
|
Open vSwitch CI |
3f9b5c |
- * per-vport and per-cpu.
|
|
Open vSwitch CI |
3f9b5c |
- *
|
|
Open vSwitch CI |
3f9b5c |
- * When dispatching upcalls per-vport, the kernel will
|
|
Open vSwitch CI |
3f9b5c |
- * send the upcall via a Netlink socket that has been selected based on the
|
|
Open vSwitch CI |
3f9b5c |
- * vport that received the packet that is causing the upcall.
|
|
Open vSwitch CI |
3f9b5c |
- *
|
|
Open vSwitch CI |
3f9b5c |
- * When dispatching upcall per-cpu, the kernel will send the upcall via
|
|
Open vSwitch CI |
3f9b5c |
- * a Netlink socket that has been selected based on the cpu that received
|
|
Open vSwitch CI |
3f9b5c |
- * the packet that is causing the upcall.
|
|
Open vSwitch CI |
3f9b5c |
- *
|
|
Open vSwitch CI |
3f9b5c |
- * First we test to see if the kernel module supports per-cpu dispatching
|
|
Open vSwitch CI |
3f9b5c |
- * (the preferred method). If it does not support per-cpu dispatching, we
|
|
Open vSwitch CI |
3f9b5c |
- * fall back to the per-vport dispatch mode.
|
|
Open vSwitch CI |
3f9b5c |
+ /* Some older kernels will not reject unknown features. This will cause
|
|
Open vSwitch CI |
3f9b5c |
+ * 'ovs-vswitchd' to incorrectly assume a feature is supported. In order to
|
|
Open vSwitch CI |
3f9b5c |
+ * test for that, we attempt to set a feature that we know is not supported
|
|
Open vSwitch CI |
3f9b5c |
+ * by any kernel. If this feature is not rejected, we can assume we are
|
|
Open vSwitch CI |
3f9b5c |
+ * running on one of these older kernels.
|
|
Open vSwitch CI |
3f9b5c |
*/
|
|
Open vSwitch CI |
3f9b5c |
dp_request.user_features |= OVS_DP_F_UNALIGNED;
|
|
Open vSwitch CI |
3f9b5c |
- dp_request.user_features &= ~OVS_DP_F_VPORT_PIDS;
|
|
Open vSwitch CI |
3f9b5c |
- dp_request.user_features |= OVS_DP_F_DISPATCH_UPCALL_PER_CPU;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features |= OVS_DP_F_VPORT_PIDS;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features |= OVS_DP_F_UNSUPPORTED;
|
|
Open vSwitch CI |
3f9b5c |
error = dpif_netlink_dp_transact(&dp_request, &dp, &buf;;
|
|
Open vSwitch CI |
3f9b5c |
if (error) {
|
|
Open vSwitch CI |
3f9b5c |
- dp_request.user_features &= ~OVS_DP_F_DISPATCH_UPCALL_PER_CPU;
|
|
Open vSwitch CI |
3f9b5c |
+ /* The Open vSwitch kernel module has two modes for dispatching
|
|
Open vSwitch CI |
3f9b5c |
+ * upcalls: per-vport and per-cpu.
|
|
Open vSwitch CI |
3f9b5c |
+ *
|
|
Open vSwitch CI |
3f9b5c |
+ * When dispatching upcalls per-vport, the kernel will
|
|
Open vSwitch CI |
3f9b5c |
+ * send the upcall via a Netlink socket that has been selected based on
|
|
Open vSwitch CI |
3f9b5c |
+ * the vport that received the packet that is causing the upcall.
|
|
Open vSwitch CI |
3f9b5c |
+ *
|
|
Open vSwitch CI |
3f9b5c |
+ * When dispatching upcall per-cpu, the kernel will send the upcall via
|
|
Open vSwitch CI |
3f9b5c |
+ * a Netlink socket that has been selected based on the cpu that
|
|
Open vSwitch CI |
3f9b5c |
+ * received the packet that is causing the upcall.
|
|
Open vSwitch CI |
3f9b5c |
+ *
|
|
Open vSwitch CI |
3f9b5c |
+ * First we test to see if the kernel module supports per-cpu
|
|
Open vSwitch CI |
3f9b5c |
+ * dispatching (the preferred method). If it does not support per-cpu
|
|
Open vSwitch CI |
3f9b5c |
+ * dispatching, we fall back to the per-vport dispatch mode.
|
|
Open vSwitch CI |
3f9b5c |
+ */
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features &= ~OVS_DP_F_UNSUPPORTED;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features |= OVS_DP_F_UNALIGNED;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features &= ~OVS_DP_F_VPORT_PIDS;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features |= OVS_DP_F_DISPATCH_UPCALL_PER_CPU;
|
|
Open vSwitch CI |
3f9b5c |
+ error = dpif_netlink_dp_transact(&dp_request, &dp, &buf;;
|
|
Open vSwitch CI |
3f9b5c |
+ if (error) {
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features &= ~OVS_DP_F_DISPATCH_UPCALL_PER_CPU;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features |= OVS_DP_F_VPORT_PIDS;
|
|
Open vSwitch CI |
3f9b5c |
+ error = dpif_netlink_dp_transact(&dp_request, &dp, &buf;;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ if (error) {
|
|
Open vSwitch CI |
3f9b5c |
+ return error;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ error = open_dpif(&dp, dpifp);
|
|
Open vSwitch CI |
3f9b5c |
+ dpif_netlink_set_features(*dpifp, OVS_DP_F_TC_RECIRC_SHARING);
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ VLOG_INFO("Kernel does not correctly support feature negotiation. "
|
|
Open vSwitch CI |
3f9b5c |
+ "Using standard features.");
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.cmd = OVS_DP_CMD_SET;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features = 0;
|
|
Open vSwitch CI |
3f9b5c |
+ dp_request.user_features |= OVS_DP_F_UNALIGNED;
|
|
Open vSwitch CI |
3f9b5c |
dp_request.user_features |= OVS_DP_F_VPORT_PIDS;
|
|
Open vSwitch CI |
3f9b5c |
error = dpif_netlink_dp_transact(&dp_request, &dp, &buf;;
|
|
Open vSwitch CI |
3f9b5c |
- }
|
|
Open vSwitch CI |
3f9b5c |
- if (error) {
|
|
Open vSwitch CI |
3f9b5c |
- return error;
|
|
Open vSwitch CI |
3f9b5c |
+ if (error) {
|
|
Open vSwitch CI |
3f9b5c |
+ return error;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ error = open_dpif(&dp, dpifp);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- error = open_dpif(&dp, dpifp);
|
|
Open vSwitch CI |
3f9b5c |
- dpif_netlink_set_features(*dpifp, OVS_DP_F_TC_RECIRC_SHARING);
|
|
Open vSwitch CI |
3f9b5c |
ofpbuf_delete(buf);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (create) {
|
|
|
110336 |
diff --git a/lib/ipf.c b/lib/ipf.c
|
|
Open vSwitch CI |
3f9b5c |
index d9f781147a..507db2aea2 100644
|
|
|
110336 |
--- a/lib/ipf.c
|
|
|
110336 |
+++ b/lib/ipf.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -943,6 +943,8 @@ ipf_extract_frags_from_batch(struct ipf *ipf, struct dp_packet_batch *pb,
|
|
Open vSwitch CI |
3f9b5c |
ovs_mutex_lock(&ipf->ipf_lock);
|
|
Open vSwitch CI |
3f9b5c |
if (!ipf_handle_frag(ipf, pkt, dl_type, zone, now, hash_basis)) {
|
|
Open vSwitch CI |
3f9b5c |
dp_packet_batch_refill(pb, pkt, pb_idx);
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ dp_packet_delete(pkt);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
ovs_mutex_unlock(&ipf->ipf_lock);
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
@@ -1152,52 +1154,56 @@ ipf_post_execute_reass_pkts(struct ipf *ipf,
|
|
|
110336 |
* NETDEV_MAX_BURST. */
|
|
|
110336 |
DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) {
|
|
|
110336 |
if (rp && pkt == rp->list->reass_execute_ctx) {
|
|
|
110336 |
+ const struct ipf_frag *frag_0 = &rp->list->frag_list[0];
|
|
|
110336 |
+ void *l4_frag = dp_packet_l4(frag_0->pkt);
|
|
|
110336 |
+ void *l4_reass = dp_packet_l4(pkt);
|
|
|
110336 |
+ memcpy(l4_frag, l4_reass, dp_packet_l4_size(frag_0->pkt));
|
|
|
110336 |
+
|
|
|
110336 |
for (int i = 0; i <= rp->list->last_inuse_idx; i++) {
|
|
|
110336 |
- rp->list->frag_list[i].pkt->md.ct_label = pkt->md.ct_label;
|
|
|
110336 |
- rp->list->frag_list[i].pkt->md.ct_mark = pkt->md.ct_mark;
|
|
|
110336 |
- rp->list->frag_list[i].pkt->md.ct_state = pkt->md.ct_state;
|
|
|
110336 |
- rp->list->frag_list[i].pkt->md.ct_zone = pkt->md.ct_zone;
|
|
|
110336 |
- rp->list->frag_list[i].pkt->md.ct_orig_tuple_ipv6 =
|
|
|
110336 |
+ const struct ipf_frag *frag_i = &rp->list->frag_list[i];
|
|
|
110336 |
+
|
|
|
110336 |
+ frag_i->pkt->md.ct_label = pkt->md.ct_label;
|
|
|
110336 |
+ frag_i->pkt->md.ct_mark = pkt->md.ct_mark;
|
|
|
110336 |
+ frag_i->pkt->md.ct_state = pkt->md.ct_state;
|
|
|
110336 |
+ frag_i->pkt->md.ct_zone = pkt->md.ct_zone;
|
|
|
110336 |
+ frag_i->pkt->md.ct_orig_tuple_ipv6 =
|
|
|
110336 |
pkt->md.ct_orig_tuple_ipv6;
|
|
|
110336 |
if (pkt->md.ct_orig_tuple_ipv6) {
|
|
|
110336 |
- rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv6 =
|
|
|
110336 |
+ frag_i->pkt->md.ct_orig_tuple.ipv6 =
|
|
|
110336 |
pkt->md.ct_orig_tuple.ipv6;
|
|
|
110336 |
} else {
|
|
|
110336 |
- rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv4 =
|
|
|
110336 |
+ frag_i->pkt->md.ct_orig_tuple.ipv4 =
|
|
|
110336 |
pkt->md.ct_orig_tuple.ipv4;
|
|
|
110336 |
}
|
|
|
110336 |
- }
|
|
|
110336 |
-
|
|
|
110336 |
- const struct ipf_frag *frag_0 = &rp->list->frag_list[0];
|
|
|
110336 |
- void *l4_frag = dp_packet_l4(frag_0->pkt);
|
|
|
110336 |
- void *l4_reass = dp_packet_l4(pkt);
|
|
|
110336 |
- memcpy(l4_frag, l4_reass, dp_packet_l4_size(frag_0->pkt));
|
|
|
110336 |
-
|
|
|
110336 |
- if (v6) {
|
|
|
110336 |
- struct ovs_16aligned_ip6_hdr *l3_frag
|
|
|
110336 |
- = dp_packet_l3(frag_0->pkt);
|
|
|
110336 |
- struct ovs_16aligned_ip6_hdr *l3_reass = dp_packet_l3(pkt);
|
|
|
110336 |
- l3_frag->ip6_src = l3_reass->ip6_src;
|
|
|
110336 |
- l3_frag->ip6_dst = l3_reass->ip6_dst;
|
|
|
110336 |
- } else {
|
|
|
110336 |
- struct ip_header *l3_frag = dp_packet_l3(frag_0->pkt);
|
|
|
110336 |
- struct ip_header *l3_reass = dp_packet_l3(pkt);
|
|
|
110336 |
- if (!dp_packet_hwol_is_ipv4(frag_0->pkt)) {
|
|
|
110336 |
- ovs_be32 reass_ip =
|
|
|
110336 |
- get_16aligned_be32(&l3_reass->ip_src);
|
|
|
110336 |
- ovs_be32 frag_ip =
|
|
|
110336 |
- get_16aligned_be32(&l3_frag->ip_src);
|
|
|
110336 |
-
|
|
|
110336 |
- l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
|
|
|
110336 |
- frag_ip, reass_ip);
|
|
|
110336 |
- reass_ip = get_16aligned_be32(&l3_reass->ip_dst);
|
|
|
110336 |
- frag_ip = get_16aligned_be32(&l3_frag->ip_dst);
|
|
|
110336 |
- l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
|
|
|
110336 |
- frag_ip, reass_ip);
|
|
|
110336 |
+ if (v6) {
|
|
|
110336 |
+ struct ovs_16aligned_ip6_hdr *l3_frag
|
|
|
110336 |
+ = dp_packet_l3(frag_i->pkt);
|
|
|
110336 |
+ struct ovs_16aligned_ip6_hdr *l3_reass
|
|
|
110336 |
+ = dp_packet_l3(pkt);
|
|
|
110336 |
+ l3_frag->ip6_src = l3_reass->ip6_src;
|
|
|
110336 |
+ l3_frag->ip6_dst = l3_reass->ip6_dst;
|
|
|
110336 |
+ } else {
|
|
|
110336 |
+ struct ip_header *l3_frag = dp_packet_l3(frag_i->pkt);
|
|
|
110336 |
+ struct ip_header *l3_reass = dp_packet_l3(pkt);
|
|
|
110336 |
+ if (!dp_packet_hwol_is_ipv4(frag_i->pkt)) {
|
|
|
110336 |
+ ovs_be32 reass_ip =
|
|
|
110336 |
+ get_16aligned_be32(&l3_reass->ip_src);
|
|
|
110336 |
+ ovs_be32 frag_ip =
|
|
|
110336 |
+ get_16aligned_be32(&l3_frag->ip_src);
|
|
|
110336 |
+
|
|
|
110336 |
+ l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
|
|
|
110336 |
+ frag_ip,
|
|
|
110336 |
+ reass_ip);
|
|
|
110336 |
+ reass_ip = get_16aligned_be32(&l3_reass->ip_dst);
|
|
|
110336 |
+ frag_ip = get_16aligned_be32(&l3_frag->ip_dst);
|
|
|
110336 |
+ l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
|
|
|
110336 |
+ frag_ip,
|
|
|
110336 |
+ reass_ip);
|
|
|
110336 |
+ }
|
|
|
110336 |
+
|
|
|
110336 |
+ l3_frag->ip_src = l3_reass->ip_src;
|
|
|
110336 |
+ l3_frag->ip_dst = l3_reass->ip_dst;
|
|
|
110336 |
}
|
|
|
110336 |
-
|
|
|
110336 |
- l3_frag->ip_src = l3_reass->ip_src;
|
|
|
110336 |
- l3_frag->ip_dst = l3_reass->ip_dst;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
ipf_completed_list_add(&ipf->frag_complete_list, rp->list);
|
|
|
110336 |
diff --git a/lib/json.c b/lib/json.c
|
|
|
110336 |
index 32d25003b8..0baf7c622c 100644
|
|
|
110336 |
--- a/lib/json.c
|
|
|
110336 |
+++ b/lib/json.c
|
|
|
110336 |
@@ -146,6 +146,7 @@ json_type_to_string(enum json_type type)
|
|
|
110336 |
case JSON_STRING:
|
|
|
110336 |
return "string";
|
|
|
110336 |
|
|
|
110336 |
+ case JSON_SERIALIZED_OBJECT:
|
|
|
110336 |
case JSON_N_TYPES:
|
|
|
110336 |
default:
|
|
|
110336 |
return "<invalid>";
|
|
|
110336 |
@@ -180,6 +181,14 @@ json_string_create(const char *s)
|
|
|
110336 |
return json_string_create_nocopy(xstrdup(s));
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
+struct json *
|
|
|
110336 |
+json_serialized_object_create(const struct json *src)
|
|
|
110336 |
+{
|
|
|
110336 |
+ struct json *json = json_create(JSON_SERIALIZED_OBJECT);
|
|
|
110336 |
+ json->string = json_to_string(src, JSSF_SORT);
|
|
|
110336 |
+ return json;
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
struct json *
|
|
|
110336 |
json_array_create_empty(void)
|
|
|
110336 |
{
|
|
|
110336 |
@@ -309,6 +318,13 @@ json_string(const struct json *json)
|
|
|
110336 |
return json->string;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
+const char *
|
|
|
110336 |
+json_serialized_object(const struct json *json)
|
|
|
110336 |
+{
|
|
|
110336 |
+ ovs_assert(json->type == JSON_SERIALIZED_OBJECT);
|
|
|
110336 |
+ return json->string;
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
struct json_array *
|
|
|
110336 |
json_array(const struct json *json)
|
|
|
110336 |
{
|
|
|
110336 |
@@ -362,6 +378,7 @@ json_destroy(struct json *json)
|
|
|
110336 |
break;
|
|
|
110336 |
|
|
|
110336 |
case JSON_STRING:
|
|
|
110336 |
+ case JSON_SERIALIZED_OBJECT:
|
|
|
110336 |
free(json->string);
|
|
|
110336 |
break;
|
|
|
110336 |
|
|
|
110336 |
@@ -422,6 +439,9 @@ json_deep_clone(const struct json *json)
|
|
|
110336 |
case JSON_STRING:
|
|
|
110336 |
return json_string_create(json->string);
|
|
|
110336 |
|
|
|
110336 |
+ case JSON_SERIALIZED_OBJECT:
|
|
|
110336 |
+ return json_serialized_object_create(json);
|
|
|
110336 |
+
|
|
|
110336 |
case JSON_NULL:
|
|
|
110336 |
case JSON_FALSE:
|
|
|
110336 |
case JSON_TRUE:
|
|
|
110336 |
@@ -521,6 +541,7 @@ json_hash(const struct json *json, size_t basis)
|
|
|
110336 |
return json_hash_array(&json->array, basis);
|
|
|
110336 |
|
|
|
110336 |
case JSON_STRING:
|
|
|
110336 |
+ case JSON_SERIALIZED_OBJECT:
|
|
|
110336 |
return hash_string(json->string, basis);
|
|
|
110336 |
|
|
|
110336 |
case JSON_NULL:
|
|
|
110336 |
@@ -596,6 +617,7 @@ json_equal(const struct json *a, const struct json *b)
|
|
|
110336 |
return json_equal_array(&a->array, &b->array);
|
|
|
110336 |
|
|
|
110336 |
case JSON_STRING:
|
|
|
110336 |
+ case JSON_SERIALIZED_OBJECT:
|
|
|
110336 |
return !strcmp(a->string, b->string);
|
|
|
110336 |
|
|
|
110336 |
case JSON_NULL:
|
|
|
110336 |
@@ -1072,6 +1094,14 @@ json_from_string(const char *string)
|
|
|
110336 |
return json_parser_finish(p);
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
+/* Parses data of JSON_SERIALIZED_OBJECT to the real JSON. */
|
|
|
110336 |
+struct json *
|
|
|
110336 |
+json_from_serialized_object(const struct json *json)
|
|
|
110336 |
+{
|
|
|
110336 |
+ ovs_assert(json->type == JSON_SERIALIZED_OBJECT);
|
|
|
110336 |
+ return json_from_string(json->string);
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
/* Reads the file named 'file_name', parses its contents as a JSON object or
|
|
|
110336 |
* array, and returns a newly allocated 'struct json'. The caller must free
|
|
|
110336 |
* the returned structure with json_destroy() when it is no longer needed.
|
|
|
110336 |
@@ -1563,6 +1593,10 @@ json_serialize(const struct json *json, struct json_serializer *s)
|
|
|
110336 |
json_serialize_string(json->string, ds);
|
|
|
110336 |
break;
|
|
|
110336 |
|
|
|
110336 |
+ case JSON_SERIALIZED_OBJECT:
|
|
|
110336 |
+ ds_put_cstr(ds, json->string);
|
|
|
110336 |
+ break;
|
|
|
110336 |
+
|
|
|
110336 |
case JSON_N_TYPES:
|
|
|
110336 |
default:
|
|
|
110336 |
OVS_NOT_REACHED();
|
|
|
110336 |
@@ -1696,14 +1730,30 @@ json_serialize_string(const char *string, struct ds *ds)
|
|
|
110336 |
{
|
|
|
110336 |
uint8_t c;
|
|
|
110336 |
uint8_t c2;
|
|
|
110336 |
+ size_t count;
|
|
|
110336 |
const char *escape;
|
|
|
110336 |
+ const char *start;
|
|
|
110336 |
|
|
|
110336 |
ds_put_char(ds, '"');
|
|
|
110336 |
+ count = 0;
|
|
|
110336 |
+ start = string;
|
|
|
110336 |
while ((c = *string++) != '\0') {
|
|
|
110336 |
- escape = chars_escaping[c];
|
|
|
110336 |
- while ((c2 = *escape++) != '\0') {
|
|
|
110336 |
- ds_put_char(ds, c2);
|
|
|
110336 |
+ if (c >= ' ' && c != '"' && c != '\\') {
|
|
|
110336 |
+ count++;
|
|
|
110336 |
+ } else {
|
|
|
110336 |
+ if (count) {
|
|
|
110336 |
+ ds_put_buffer(ds, start, count);
|
|
|
110336 |
+ count = 0;
|
|
|
110336 |
+ }
|
|
|
110336 |
+ start = string;
|
|
|
110336 |
+ escape = chars_escaping[c];
|
|
|
110336 |
+ while ((c2 = *escape++) != '\0') {
|
|
|
110336 |
+ ds_put_char(ds, c2);
|
|
|
110336 |
+ }
|
|
|
110336 |
}
|
|
|
110336 |
}
|
|
|
110336 |
+ if (count) {
|
|
|
110336 |
+ ds_put_buffer(ds, start, count);
|
|
|
110336 |
+ }
|
|
|
110336 |
ds_put_char(ds, '"');
|
|
|
110336 |
}
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
|
|
Open vSwitch CI |
3f9b5c |
index c808d205d5..e03cd8d0c5 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/meta-flow.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/meta-flow.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -1788,6 +1788,19 @@ mf_is_tun_metadata(const struct mf_field *mf)
|
|
Open vSwitch CI |
3f9b5c |
mf->id < MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+bool
|
|
Open vSwitch CI |
3f9b5c |
+mf_is_frozen_metadata(const struct mf_field *mf)
|
|
Open vSwitch CI |
3f9b5c |
+{
|
|
Open vSwitch CI |
3f9b5c |
+ if (mf->id >= MFF_TUN_ID && mf->id <= MFF_IN_PORT_OXM) {
|
|
Open vSwitch CI |
3f9b5c |
+ return true;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ if (mf->id >= MFF_REG0 && mf->id < MFF_ETH_SRC) {
|
|
Open vSwitch CI |
3f9b5c |
+ return true;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ return false;
|
|
Open vSwitch CI |
3f9b5c |
+}
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
bool
|
|
Open vSwitch CI |
3f9b5c |
mf_is_pipeline_field(const struct mf_field *mf)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
|
110336 |
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
|
|
|
110336 |
index 45a96b9be2..ca92c947a2 100644
|
|
|
110336 |
--- a/lib/netdev-dpdk.c
|
|
|
110336 |
+++ b/lib/netdev-dpdk.c
|
|
|
110336 |
@@ -961,14 +961,6 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq)
|
|
|
110336 |
|
|
|
110336 |
rte_eth_dev_info_get(dev->port_id, &info;;
|
|
|
110336 |
|
|
|
110336 |
- /* As of DPDK 19.11, it is not allowed to set a mq_mode for
|
|
|
110336 |
- * virtio PMD driver. */
|
|
|
110336 |
- if (!strcmp(info.driver_name, "net_virtio")) {
|
|
|
110336 |
- conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
|
|
|
110336 |
- } else {
|
|
|
110336 |
- conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
|
|
|
110336 |
- }
|
|
|
110336 |
-
|
|
|
110336 |
/* As of DPDK 17.11.1 a few PMDs require to explicitly enable
|
|
|
110336 |
* scatter to support jumbo RX.
|
|
|
110336 |
* Setting scatter for the device is done after checking for
|
|
|
110336 |
@@ -1000,6 +992,11 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq)
|
|
|
110336 |
/* Limit configured rss hash functions to only those supported
|
|
|
110336 |
* by the eth device. */
|
|
|
110336 |
conf.rx_adv_conf.rss_conf.rss_hf &= info.flow_type_rss_offloads;
|
|
|
110336 |
+ if (conf.rx_adv_conf.rss_conf.rss_hf == 0) {
|
|
|
110336 |
+ conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
|
|
|
110336 |
+ } else {
|
|
|
110336 |
+ conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
|
|
|
110336 |
+ }
|
|
|
110336 |
|
|
|
110336 |
/* A device may report more queues than it makes available (this has
|
|
|
110336 |
* been observed for Intel xl710, which reserves some of them for
|
|
|
110336 |
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
|
|
|
110336 |
index 60dd138914..97bd21be4a 100644
|
|
|
110336 |
--- a/lib/netdev-linux.c
|
|
|
110336 |
+++ b/lib/netdev-linux.c
|
|
|
110336 |
@@ -627,6 +627,7 @@ netdev_linux_notify_sock(void)
|
|
|
110336 |
if (!error) {
|
|
|
110336 |
size_t i;
|
|
|
110336 |
|
|
|
110336 |
+ nl_sock_listen_all_nsid(sock, true);
|
|
|
110336 |
for (i = 0; i < ARRAY_SIZE(mcgroups); i++) {
|
|
|
110336 |
error = nl_sock_join_mcgroup(sock, mcgroups[i]);
|
|
|
110336 |
if (error) {
|
|
|
110336 |
@@ -636,7 +637,6 @@ netdev_linux_notify_sock(void)
|
|
|
110336 |
}
|
|
|
110336 |
}
|
|
|
110336 |
}
|
|
|
110336 |
- nl_sock_listen_all_nsid(sock, true);
|
|
|
110336 |
ovsthread_once_done(&once);
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
diff --git a/lib/odp-util.c b/lib/odp-util.c
|
|
|
110336 |
index 7729a90608..fbdfc7ad83 100644
|
|
|
110336 |
--- a/lib/odp-util.c
|
|
|
110336 |
+++ b/lib/odp-util.c
|
|
|
110336 |
@@ -2941,7 +2941,7 @@ odp_nsh_key_from_attr__(const struct nlattr *attr, bool is_mask,
|
|
|
110336 |
const struct ovs_nsh_key_md1 *md1 = nl_attr_get(a);
|
|
|
110336 |
has_md1 = true;
|
|
|
110336 |
memcpy(nsh->context, md1->context, sizeof md1->context);
|
|
|
110336 |
- if (len == 2 * sizeof(*md1)) {
|
|
|
110336 |
+ if (nsh_mask && (len == 2 * sizeof *md1)) {
|
|
|
110336 |
const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
|
|
|
110336 |
memcpy(nsh_mask->context, md1_mask->context,
|
|
|
110336 |
sizeof(*md1_mask));
|
|
|
110336 |
@@ -4618,7 +4618,7 @@ odp_flow_format(const struct nlattr *key, size_t key_len,
|
|
|
110336 |
}
|
|
|
110336 |
ds_put_char(ds, ')');
|
|
|
110336 |
}
|
|
|
110336 |
- if (!has_ethtype_key) {
|
|
|
110336 |
+ if (!has_ethtype_key && mask) {
|
|
|
110336 |
const struct nlattr *ma = nl_attr_find__(mask, mask_len,
|
|
|
110336 |
OVS_KEY_ATTR_ETHERTYPE);
|
|
|
110336 |
if (ma) {
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/ovsdb-cs.c b/lib/ovsdb-cs.c
|
|
Open vSwitch CI |
3f9b5c |
index 659d49dbf7..fcb6fe1b34 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/ovsdb-cs.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/ovsdb-cs.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -1833,7 +1833,7 @@ server_column_get_string(const struct server_row *row,
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
ovs_assert(server_columns[index].type.key.type == OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *d = &row->data[index];
|
|
Open vSwitch CI |
3f9b5c |
- return d->n == 1 ? d->keys[0].string : default_value;
|
|
Open vSwitch CI |
3f9b5c |
+ return d->n == 1 ? d->keys[0].s->string : default_value;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
static bool
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/ovsdb-data.c b/lib/ovsdb-data.c
|
|
Open vSwitch CI |
3f9b5c |
index c145f5ad97..6654ed6deb 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/ovsdb-data.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/ovsdb-data.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -74,7 +74,7 @@ ovsdb_atom_init_default(union ovsdb_atom *atom, enum ovsdb_atomic_type type)
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- atom->string = xmemdup("", 1);
|
|
Open vSwitch CI |
3f9b5c |
+ atom->s = ovsdb_atom_string_create_nocopy(xmemdup("", 1));
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_UUID:
|
|
Open vSwitch CI |
3f9b5c |
@@ -136,7 +136,7 @@ ovsdb_atom_is_default(const union ovsdb_atom *atom,
|
|
Open vSwitch CI |
3f9b5c |
return atom->boolean == false;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- return atom->string[0] == '\0';
|
|
Open vSwitch CI |
3f9b5c |
+ return atom->s->string[0] == '\0';
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_UUID:
|
|
Open vSwitch CI |
3f9b5c |
return uuid_is_zero(&atom->uuid);
|
|
Open vSwitch CI |
3f9b5c |
@@ -172,7 +172,8 @@ ovsdb_atom_clone(union ovsdb_atom *new, const union ovsdb_atom *old,
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- new->string = xstrdup(old->string);
|
|
Open vSwitch CI |
3f9b5c |
+ new->s = old->s;
|
|
Open vSwitch CI |
3f9b5c |
+ new->s->n_refs++;
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_UUID:
|
|
Open vSwitch CI |
3f9b5c |
@@ -214,7 +215,7 @@ ovsdb_atom_hash(const union ovsdb_atom *atom, enum ovsdb_atomic_type type,
|
|
Open vSwitch CI |
3f9b5c |
return hash_boolean(atom->boolean, basis);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- return hash_string(atom->string, basis);
|
|
Open vSwitch CI |
3f9b5c |
+ return hash_string(atom->s->string, basis);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_UUID:
|
|
Open vSwitch CI |
3f9b5c |
return hash_int(uuid_hash(&atom->uuid), basis);
|
|
Open vSwitch CI |
3f9b5c |
@@ -246,7 +247,7 @@ ovsdb_atom_compare_3way(const union ovsdb_atom *a,
|
|
Open vSwitch CI |
3f9b5c |
return a->boolean - b->boolean;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- return strcmp(a->string, b->string);
|
|
Open vSwitch CI |
3f9b5c |
+ return a->s == b->s ? 0 : strcmp(a->s->string, b->s->string);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_UUID:
|
|
Open vSwitch CI |
3f9b5c |
return uuid_compare_3way(&a->uuid, &b->uuid);
|
|
Open vSwitch CI |
3f9b5c |
@@ -404,7 +405,7 @@ ovsdb_atom_from_json__(union ovsdb_atom *atom,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
if (json->type == JSON_STRING) {
|
|
Open vSwitch CI |
3f9b5c |
- atom->string = xstrdup(json->string);
|
|
Open vSwitch CI |
3f9b5c |
+ atom->s = ovsdb_atom_string_create(json->string);
|
|
Open vSwitch CI |
3f9b5c |
return NULL;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
@@ -473,7 +474,7 @@ ovsdb_atom_to_json(const union ovsdb_atom *atom, enum ovsdb_atomic_type type)
|
|
Open vSwitch CI |
3f9b5c |
return json_boolean_create(atom->boolean);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- return json_string_create(atom->string);
|
|
Open vSwitch CI |
3f9b5c |
+ return json_string_create(atom->s->string);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_UUID:
|
|
Open vSwitch CI |
3f9b5c |
return wrap_json("uuid", json_string_create_nocopy(
|
|
Open vSwitch CI |
3f9b5c |
@@ -551,14 +552,18 @@ ovsdb_atom_from_string__(union ovsdb_atom *atom,
|
|
Open vSwitch CI |
3f9b5c |
if (s_len < 2 || s[s_len - 1] != '"') {
|
|
Open vSwitch CI |
3f9b5c |
return xasprintf("%s: missing quote at end of "
|
|
Open vSwitch CI |
3f9b5c |
"quoted string", s);
|
|
Open vSwitch CI |
3f9b5c |
- } else if (!json_string_unescape(s + 1, s_len - 2,
|
|
Open vSwitch CI |
3f9b5c |
- &atom->string)) {
|
|
Open vSwitch CI |
3f9b5c |
- char *error = xasprintf("%s: %s", s, atom->string);
|
|
Open vSwitch CI |
3f9b5c |
- free(atom->string);
|
|
Open vSwitch CI |
3f9b5c |
- return error;
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ char *res;
|
|
Open vSwitch CI |
3f9b5c |
+ if (json_string_unescape(s + 1, s_len - 2, &res)) {
|
|
Open vSwitch CI |
3f9b5c |
+ atom->s = ovsdb_atom_string_create_nocopy(res);
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ char *error = xasprintf("%s: %s", s, res);
|
|
Open vSwitch CI |
3f9b5c |
+ free(res);
|
|
Open vSwitch CI |
3f9b5c |
+ return error;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
- atom->string = xstrdup(s);
|
|
Open vSwitch CI |
3f9b5c |
+ atom->s = ovsdb_atom_string_create(s);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -721,14 +726,14 @@ ovsdb_atom_to_string(const union ovsdb_atom *atom, enum ovsdb_atomic_type type,
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- if (string_needs_quotes(atom->string)) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (string_needs_quotes(atom->s->string)) {
|
|
Open vSwitch CI |
3f9b5c |
struct json json;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
json.type = JSON_STRING;
|
|
Open vSwitch CI |
3f9b5c |
- json.string = atom->string;
|
|
Open vSwitch CI |
3f9b5c |
+ json.string = atom->s->string;
|
|
Open vSwitch CI |
3f9b5c |
json_to_ds(&json, 0, out);
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
- ds_put_cstr(out, atom->string);
|
|
Open vSwitch CI |
3f9b5c |
+ ds_put_cstr(out, atom->s->string);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -750,7 +755,7 @@ ovsdb_atom_to_bare(const union ovsdb_atom *atom, enum ovsdb_atomic_type type,
|
|
Open vSwitch CI |
3f9b5c |
struct ds *out)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
if (type == OVSDB_TYPE_STRING) {
|
|
Open vSwitch CI |
3f9b5c |
- ds_put_cstr(out, atom->string);
|
|
Open vSwitch CI |
3f9b5c |
+ ds_put_cstr(out, atom->s->string);
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_atom_to_string(atom, type, out);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
@@ -799,7 +804,7 @@ ovsdb_atom_check_constraints(const union ovsdb_atom *atom,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_base_type *base)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
if (base->enum_
|
|
Open vSwitch CI |
3f9b5c |
- && ovsdb_datum_find_key(base->enum_, atom, base->type) == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ && !ovsdb_datum_find_key(base->enum_, atom, base->type, NULL)) {
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_error *error;
|
|
Open vSwitch CI |
3f9b5c |
struct ds actual = DS_EMPTY_INITIALIZER;
|
|
Open vSwitch CI |
3f9b5c |
struct ds valid = DS_EMPTY_INITIALIZER;
|
|
Open vSwitch CI |
3f9b5c |
@@ -877,7 +882,7 @@ ovsdb_atom_check_constraints(const union ovsdb_atom *atom,
|
|
Open vSwitch CI |
3f9b5c |
return NULL;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_STRING:
|
|
Open vSwitch CI |
3f9b5c |
- return check_string_constraints(atom->string, &base->string);
|
|
Open vSwitch CI |
3f9b5c |
+ return check_string_constraints(atom->s->string, &base->string);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_TYPE_UUID:
|
|
Open vSwitch CI |
3f9b5c |
return NULL;
|
|
Open vSwitch CI |
3f9b5c |
@@ -1691,8 +1696,8 @@ ovsdb_datum_from_smap(struct ovsdb_datum *datum, const struct smap *smap)
|
|
Open vSwitch CI |
3f9b5c |
struct smap_node *node;
|
|
Open vSwitch CI |
3f9b5c |
size_t i = 0;
|
|
Open vSwitch CI |
3f9b5c |
SMAP_FOR_EACH (node, smap) {
|
|
Open vSwitch CI |
3f9b5c |
- datum->keys[i].string = xstrdup(node->key);
|
|
Open vSwitch CI |
3f9b5c |
- datum->values[i].string = xstrdup(node->value);
|
|
Open vSwitch CI |
3f9b5c |
+ datum->keys[i].s = ovsdb_atom_string_create(node->key);
|
|
Open vSwitch CI |
3f9b5c |
+ datum->values[i].s = ovsdb_atom_string_create(node->value);
|
|
Open vSwitch CI |
3f9b5c |
i++;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
ovs_assert(i == datum->n);
|
|
Open vSwitch CI |
3f9b5c |
@@ -1784,14 +1789,16 @@ ovsdb_datum_compare_3way(const struct ovsdb_datum *a,
|
|
Open vSwitch CI |
3f9b5c |
a->n));
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
-/* If 'key' is one of the keys in 'datum', returns its index within 'datum',
|
|
Open vSwitch CI |
3f9b5c |
- * otherwise UINT_MAX. 'key.type' must be the type of the atoms stored in the
|
|
Open vSwitch CI |
3f9b5c |
- * 'keys' array in 'datum'.
|
|
Open vSwitch CI |
3f9b5c |
+/* If 'key' is one of the keys in 'datum', returns 'true' and sets '*pos' to
|
|
Open vSwitch CI |
3f9b5c |
+ * its index within 'datum', otherwise returns 'false' and sets '*pos' to the
|
|
Open vSwitch CI |
3f9b5c |
+ * index where 'key' should have been. 'key.type' must be the type of the
|
|
Open vSwitch CI |
3f9b5c |
+ * atoms stored in the 'keys' array in 'datum'.
|
|
Open vSwitch CI |
3f9b5c |
*/
|
|
Open vSwitch CI |
3f9b5c |
-unsigned int
|
|
Open vSwitch CI |
3f9b5c |
+bool
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_find_key(const struct ovsdb_datum *datum,
|
|
Open vSwitch CI |
3f9b5c |
const union ovsdb_atom *key,
|
|
Open vSwitch CI |
3f9b5c |
- enum ovsdb_atomic_type key_type)
|
|
Open vSwitch CI |
3f9b5c |
+ enum ovsdb_atomic_type key_type,
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int *pos)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
unsigned int low = 0;
|
|
Open vSwitch CI |
3f9b5c |
unsigned int high = datum->n;
|
|
Open vSwitch CI |
3f9b5c |
@@ -1803,10 +1810,16 @@ ovsdb_datum_find_key(const struct ovsdb_datum *datum,
|
|
Open vSwitch CI |
3f9b5c |
} else if (cmp > 0) {
|
|
Open vSwitch CI |
3f9b5c |
low = idx + 1;
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
- return idx;
|
|
Open vSwitch CI |
3f9b5c |
+ if (pos) {
|
|
Open vSwitch CI |
3f9b5c |
+ *pos = idx;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ return true;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- return UINT_MAX;
|
|
Open vSwitch CI |
3f9b5c |
+ if (pos) {
|
|
Open vSwitch CI |
3f9b5c |
+ *pos = low;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ return false;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* If 'key' and 'value' is one of the key-value pairs in 'datum', returns its
|
|
Open vSwitch CI |
3f9b5c |
@@ -1821,10 +1834,11 @@ ovsdb_datum_find_key_value(const struct ovsdb_datum *datum,
|
|
Open vSwitch CI |
3f9b5c |
const union ovsdb_atom *value,
|
|
Open vSwitch CI |
3f9b5c |
enum ovsdb_atomic_type value_type)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int idx = ovsdb_datum_find_key(datum, key, key_type);
|
|
Open vSwitch CI |
3f9b5c |
- if (idx != UINT_MAX
|
|
Open vSwitch CI |
3f9b5c |
- && value_type != OVSDB_TYPE_VOID
|
|
Open vSwitch CI |
3f9b5c |
- && !ovsdb_atom_equals(&datum->values[idx], value, value_type)) {
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int idx;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_find_key(datum, key, key_type, &idx)
|
|
Open vSwitch CI |
3f9b5c |
+ || (value_type != OVSDB_TYPE_VOID
|
|
Open vSwitch CI |
3f9b5c |
+ && !ovsdb_atom_equals(&datum->values[idx], value, value_type))) {
|
|
Open vSwitch CI |
3f9b5c |
idx = UINT_MAX;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
return idx;
|
|
Open vSwitch CI |
3f9b5c |
@@ -1948,38 +1962,68 @@ ovsdb_datum_add_unsafe(struct ovsdb_datum *datum,
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+/* Adds 'n' atoms starting from index 'start_idx' from 'src' to the end of
|
|
Open vSwitch CI |
3f9b5c |
+ * 'dst'. 'dst' should have enough memory allocated to hold the additional
|
|
Open vSwitch CI |
3f9b5c |
+ * 'n' atoms. Atoms are not cloned, i.e. 'dst' will reference the same data.
|
|
Open vSwitch CI |
3f9b5c |
+ * Caller also should take care of the result being sorted. */
|
|
Open vSwitch CI |
3f9b5c |
+static void
|
|
Open vSwitch CI |
3f9b5c |
+ovsdb_datum_push_unsafe(struct ovsdb_datum *dst,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *src,
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int start_idx, unsigned int n,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_type *type)
|
|
Open vSwitch CI |
3f9b5c |
+{
|
|
Open vSwitch CI |
3f9b5c |
+ memcpy(&dst->keys[dst->n], &src->keys[start_idx], n * sizeof src->keys[0]);
|
|
Open vSwitch CI |
3f9b5c |
+ if (type->value.type != OVSDB_TYPE_VOID) {
|
|
Open vSwitch CI |
3f9b5c |
+ memcpy(&dst->values[dst->n], &src->values[start_idx],
|
|
Open vSwitch CI |
3f9b5c |
+ n * sizeof src->values[0]);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ dst->n += n;
|
|
Open vSwitch CI |
3f9b5c |
+}
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
void
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_union(struct ovsdb_datum *a, const struct ovsdb_datum *b,
|
|
Open vSwitch CI |
3f9b5c |
- const struct ovsdb_type *type, bool replace)
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_type *type)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int n;
|
|
Open vSwitch CI |
3f9b5c |
- size_t bi;
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_datum result;
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int copied, pos;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- n = a->n;
|
|
Open vSwitch CI |
3f9b5c |
- for (bi = 0; bi < b->n; bi++) {
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int ai;
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_init_empty(&result);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- ai = ovsdb_datum_find_key(a, &b->keys[bi], type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
- if (ai == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
- if (n == a->n) {
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_reallocate(a, type, a->n + (b->n - bi));
|
|
Open vSwitch CI |
3f9b5c |
- }
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_atom_clone(&a->keys[n], &b->keys[bi], type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
- if (type->value.type != OVSDB_TYPE_VOID) {
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_atom_clone(&a->values[n], &b->values[bi],
|
|
Open vSwitch CI |
3f9b5c |
- type->value.type);
|
|
Open vSwitch CI |
3f9b5c |
- }
|
|
Open vSwitch CI |
3f9b5c |
- n++;
|
|
Open vSwitch CI |
3f9b5c |
- } else if (replace && type->value.type != OVSDB_TYPE_VOID) {
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_atom_destroy(&a->values[ai], type->value.type);
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_atom_clone(&a->values[ai], &b->values[bi],
|
|
Open vSwitch CI |
3f9b5c |
+ copied = 0;
|
|
Open vSwitch CI |
3f9b5c |
+ for (size_t bi = 0; bi < b->n; bi++) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (ovsdb_datum_find_key(a, &b->keys[bi], type->key.type, &pos)) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* Atom with the same key already exists. */
|
|
Open vSwitch CI |
3f9b5c |
+ continue;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ if (!result.keys) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_reallocate(&result, type, a->n + (b->n - bi));
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ if (pos > copied) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* Need to copy some atoms from 'a' first. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_push_unsafe(&result, a, copied, pos - copied, type);
|
|
Open vSwitch CI |
3f9b5c |
+ copied = pos;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ /* Inserting new atom from 'b'. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_clone(&result.keys[result.n], &b->keys[bi], type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (type->value.type != OVSDB_TYPE_VOID) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_clone(&result.values[result.n], &b->values[bi],
|
|
Open vSwitch CI |
3f9b5c |
type->value.type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
+ result.n++;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- if (n != a->n) {
|
|
Open vSwitch CI |
3f9b5c |
- a->n = n;
|
|
Open vSwitch CI |
3f9b5c |
- ovs_assert(!ovsdb_datum_sort(a, type->key.type));
|
|
Open vSwitch CI |
3f9b5c |
+ if (!result.keys) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* 'a' doesn't need to be changed. */
|
|
Open vSwitch CI |
3f9b5c |
+ return;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ if (a->n > copied) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* Copying remaining atoms. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_push_unsafe(&result, a, copied, a->n - copied, type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
+ /* All atoms are copied now. */
|
|
Open vSwitch CI |
3f9b5c |
+ a->n = 0;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_swap(&result, a);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&result, type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
void
|
|
Open vSwitch CI |
3f9b5c |
@@ -1987,26 +2031,55 @@ ovsdb_datum_subtract(struct ovsdb_datum *a, const struct ovsdb_type *a_type,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *b,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_type *b_type)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
- bool changed = false;
|
|
Open vSwitch CI |
3f9b5c |
- size_t i;
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int *idx, ai;
|
|
Open vSwitch CI |
3f9b5c |
+ size_t n_idx;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
ovs_assert(a_type->key.type == b_type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
ovs_assert(a_type->value.type == b_type->value.type
|
|
Open vSwitch CI |
3f9b5c |
|| b_type->value.type == OVSDB_TYPE_VOID);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- /* XXX The big-O of this could easily be improved. */
|
|
Open vSwitch CI |
3f9b5c |
- for (i = 0; i < a->n; ) {
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int idx = ovsdb_datum_find(a, i, b, b_type);
|
|
Open vSwitch CI |
3f9b5c |
- if (idx != UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
- changed = true;
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_remove_unsafe(a, i, a_type);
|
|
Open vSwitch CI |
3f9b5c |
- } else {
|
|
Open vSwitch CI |
3f9b5c |
- i++;
|
|
Open vSwitch CI |
3f9b5c |
+ idx = xmalloc(b->n * sizeof *idx);
|
|
Open vSwitch CI |
3f9b5c |
+ n_idx = 0;
|
|
Open vSwitch CI |
3f9b5c |
+ for (size_t bi = 0; bi < b->n; bi++) {
|
|
Open vSwitch CI |
3f9b5c |
+ ai = ovsdb_datum_find(b, bi, a, b_type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (ai == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* No such atom in 'a'. */
|
|
Open vSwitch CI |
3f9b5c |
+ continue;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
+ /* Not destroying right away since ovsdb_datum_find() will use them. */
|
|
Open vSwitch CI |
3f9b5c |
+ idx[n_idx++] = ai;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- if (changed) {
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_sort_assert(a, a_type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (!n_idx) {
|
|
Open vSwitch CI |
3f9b5c |
+ free(idx);
|
|
Open vSwitch CI |
3f9b5c |
+ return;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_datum result;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_init_empty(&result);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_reallocate(&result, a_type, a->n - n_idx);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int start_idx = 0;
|
|
Open vSwitch CI |
3f9b5c |
+ for (size_t i = 0; i < n_idx; i++) {
|
|
Open vSwitch CI |
3f9b5c |
+ ai = idx[i];
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ /* Destroying atom. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_destroy(&a->keys[ai], a_type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (a_type->value.type != OVSDB_TYPE_VOID) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_destroy(&a->values[ai], a_type->value.type);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ /* Copy non-removed atoms from 'a' to result. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_push_unsafe(&result, a, start_idx, ai - start_idx, a_type);
|
|
Open vSwitch CI |
3f9b5c |
+ start_idx = idx[i] + 1;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
+ /* Copying remaining atoms. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_push_unsafe(&result, a, start_idx, a->n - start_idx, a_type);
|
|
Open vSwitch CI |
3f9b5c |
+ a->n = 0;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_swap(&result, a);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&result, a_type);
|
|
Open vSwitch CI |
3f9b5c |
+ free(idx);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_symbol_table *
|
|
Open vSwitch CI |
3f9b5c |
@@ -2067,6 +2140,64 @@ ovsdb_symbol_table_insert(struct ovsdb_symbol_table *symtab,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* APIs for Generating and apply diffs. */
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+/* Find what needs to be added to and removed from 'old' to construct 'new'.
|
|
Open vSwitch CI |
3f9b5c |
+ *
|
|
Open vSwitch CI |
3f9b5c |
+ * The 'added' and 'removed' datums are always safe; the orders of keys are
|
|
Open vSwitch CI |
3f9b5c |
+ * maintained since they are added in order. */
|
|
Open vSwitch CI |
3f9b5c |
+void
|
|
Open vSwitch CI |
3f9b5c |
+ovsdb_datum_added_removed(struct ovsdb_datum *added,
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_datum *removed,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *old,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *new,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_type *type)
|
|
Open vSwitch CI |
3f9b5c |
+{
|
|
Open vSwitch CI |
3f9b5c |
+ size_t oi, ni;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_init_empty(added);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_init_empty(removed);
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_type_is_composite(type)) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_clone(removed, old, type);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_clone(added, new, type);
|
|
Open vSwitch CI |
3f9b5c |
+ return;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ /* Generate the diff in O(n) time. */
|
|
Open vSwitch CI |
3f9b5c |
+ for (oi = ni = 0; oi < old->n && ni < new->n;) {
|
|
Open vSwitch CI |
3f9b5c |
+ int c = ovsdb_atom_compare_3way(&old->keys[oi], &new->keys[ni],
|
|
Open vSwitch CI |
3f9b5c |
+ type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (c < 0) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_add_unsafe(removed, &old->keys[oi], &old->values[oi],
|
|
Open vSwitch CI |
3f9b5c |
+ type, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ oi++;
|
|
Open vSwitch CI |
3f9b5c |
+ } else if (c > 0) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_add_unsafe(added, &new->keys[ni], &new->values[ni],
|
|
Open vSwitch CI |
3f9b5c |
+ type, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ ni++;
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ if (type->value.type != OVSDB_TYPE_VOID &&
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_compare_3way(&old->values[oi], &new->values[ni],
|
|
Open vSwitch CI |
3f9b5c |
+ type->value.type)) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_add_unsafe(removed, &old->keys[oi],
|
|
Open vSwitch CI |
3f9b5c |
+ &old->values[oi], type, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_add_unsafe(added, &new->keys[ni], &new->values[ni],
|
|
Open vSwitch CI |
3f9b5c |
+ type, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ oi++; ni++;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ for (; oi < old->n; oi++) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_add_unsafe(removed, &old->keys[oi], &old->values[oi],
|
|
Open vSwitch CI |
3f9b5c |
+ type, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ for (; ni < new->n; ni++) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_add_unsafe(added, &new->keys[ni], &new->values[ni],
|
|
Open vSwitch CI |
3f9b5c |
+ type, NULL);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+}
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/* Generate a difference ovsdb_dataum between 'old' and 'new'.
|
|
Open vSwitch CI |
3f9b5c |
* 'new' can be regenerated by applying the difference to the 'old'.
|
|
Open vSwitch CI |
3f9b5c |
*
|
|
Open vSwitch CI |
3f9b5c |
@@ -2127,6 +2258,106 @@ ovsdb_datum_diff(struct ovsdb_datum *diff,
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+/* Apply 'diff' to 'a'.
|
|
Open vSwitch CI |
3f9b5c |
+ *
|
|
Open vSwitch CI |
3f9b5c |
+ * Return NULL if the 'a' is successfully updated, otherwise, return
|
|
Open vSwitch CI |
3f9b5c |
+ * ovsdb_error. */
|
|
Open vSwitch CI |
3f9b5c |
+struct ovsdb_error *
|
|
Open vSwitch CI |
3f9b5c |
+ovsdb_datum_apply_diff_in_place(struct ovsdb_datum *a,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *diff,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_type *type)
|
|
Open vSwitch CI |
3f9b5c |
+{
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_error *error = NULL;
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_datum result;
|
|
Open vSwitch CI |
3f9b5c |
+ size_t i, new_size;
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int *idx, pos;
|
|
Open vSwitch CI |
3f9b5c |
+ enum {
|
|
Open vSwitch CI |
3f9b5c |
+ DIFF_OP_ADD,
|
|
Open vSwitch CI |
3f9b5c |
+ DIFF_OP_REMOVE,
|
|
Open vSwitch CI |
3f9b5c |
+ DIFF_OP_UPDATE,
|
|
Open vSwitch CI |
3f9b5c |
+ } *operation;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_type_is_composite(type)) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(a, type);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_clone(a, diff, type);
|
|
Open vSwitch CI |
3f9b5c |
+ return NULL;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ operation = xmalloc(diff->n * sizeof *operation);
|
|
Open vSwitch CI |
3f9b5c |
+ idx = xmalloc(diff->n * sizeof *idx);
|
|
Open vSwitch CI |
3f9b5c |
+ new_size = a->n;
|
|
Open vSwitch CI |
3f9b5c |
+ for (i = 0; i < diff->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_find_key(a, &diff->keys[i], type->key.type, &pos)) {
|
|
Open vSwitch CI |
3f9b5c |
+ operation[i] = DIFF_OP_ADD;
|
|
Open vSwitch CI |
3f9b5c |
+ new_size++;
|
|
Open vSwitch CI |
3f9b5c |
+ } else if (type->value.type != OVSDB_TYPE_VOID
|
|
Open vSwitch CI |
3f9b5c |
+ && !ovsdb_atom_equals(&diff->values[i], &a->values[pos],
|
|
Open vSwitch CI |
3f9b5c |
+ type->value.type)) {
|
|
Open vSwitch CI |
3f9b5c |
+ operation[i] = DIFF_OP_UPDATE;
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ operation[i] = DIFF_OP_REMOVE;
|
|
Open vSwitch CI |
3f9b5c |
+ new_size--;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ idx[i] = pos;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ /* Make sure member size of 'new' conforms to type. */
|
|
Open vSwitch CI |
3f9b5c |
+ if (new_size < type->n_min || new_size > type->n_max) {
|
|
Open vSwitch CI |
3f9b5c |
+ error = ovsdb_error(NULL, "Datum crated by diff has size error");
|
|
Open vSwitch CI |
3f9b5c |
+ goto exit;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_init_empty(&result);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_reallocate(&result, type, new_size);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int copied = 0;
|
|
Open vSwitch CI |
3f9b5c |
+ for (i = 0; i < diff->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
+ pos = idx[i];
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ if (copied < pos) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* Copying all atoms that should go before the current one. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_push_unsafe(&result, a, copied, pos - copied, type);
|
|
Open vSwitch CI |
3f9b5c |
+ copied = pos;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ switch (operation[i]) {
|
|
Open vSwitch CI |
3f9b5c |
+ case DIFF_OP_UPDATE:
|
|
Open vSwitch CI |
3f9b5c |
+ case DIFF_OP_ADD:
|
|
Open vSwitch CI |
3f9b5c |
+ /* Inserting new atom from 'diff'. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_clone(&result.keys[result.n],
|
|
Open vSwitch CI |
3f9b5c |
+ &diff->keys[i], type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (type->value.type != OVSDB_TYPE_VOID) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_clone(&result.values[result.n],
|
|
Open vSwitch CI |
3f9b5c |
+ &diff->values[i], type->value.type);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ result.n++;
|
|
Open vSwitch CI |
3f9b5c |
+ if (operation[i] != DIFF_OP_UPDATE) {
|
|
Open vSwitch CI |
3f9b5c |
+ break;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ /* fall through */
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ case DIFF_OP_REMOVE:
|
|
Open vSwitch CI |
3f9b5c |
+ /* Destroying atom. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_destroy(&a->keys[pos], type->key.type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (type->value.type != OVSDB_TYPE_VOID) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_destroy(&a->values[pos], type->value.type);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ copied++; /* Skipping removed atom. */
|
|
Open vSwitch CI |
3f9b5c |
+ break;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ /* Copying remaining atoms. */
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_push_unsafe(&result, a, copied, a->n - copied, type);
|
|
Open vSwitch CI |
3f9b5c |
+ a->n = 0;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_swap(&result, a);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&result, type);
|
|
Open vSwitch CI |
3f9b5c |
+exit:
|
|
Open vSwitch CI |
3f9b5c |
+ free(operation);
|
|
Open vSwitch CI |
3f9b5c |
+ free(idx);
|
|
Open vSwitch CI |
3f9b5c |
+ return error;
|
|
Open vSwitch CI |
3f9b5c |
+}
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/* Apply 'diff' to 'old' to regenerate 'new'.
|
|
Open vSwitch CI |
3f9b5c |
*
|
|
Open vSwitch CI |
3f9b5c |
* Return NULL if the 'new' is successfully generated, otherwise, return
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/ovsdb-data.h b/lib/ovsdb-data.h
|
|
Open vSwitch CI |
3f9b5c |
index c5a80ee39f..f66ed3472c 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/ovsdb-data.h
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/ovsdb-data.h
|
|
Open vSwitch CI |
3f9b5c |
@@ -20,6 +20,7 @@
|
|
Open vSwitch CI |
3f9b5c |
#include "compiler.h"
|
|
Open vSwitch CI |
3f9b5c |
#include "ovsdb-types.h"
|
|
Open vSwitch CI |
3f9b5c |
#include "openvswitch/shash.h"
|
|
Open vSwitch CI |
3f9b5c |
+#include "util.h"
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
#ifdef __cplusplus
|
|
Open vSwitch CI |
3f9b5c |
extern "C" {
|
|
Open vSwitch CI |
3f9b5c |
@@ -31,12 +32,33 @@ struct ds;
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_symbol_table;
|
|
Open vSwitch CI |
3f9b5c |
struct smap;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+struct ovsdb_atom_string {
|
|
Open vSwitch CI |
3f9b5c |
+ char *string;
|
|
Open vSwitch CI |
3f9b5c |
+ size_t n_refs;
|
|
Open vSwitch CI |
3f9b5c |
+};
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+static inline struct ovsdb_atom_string *
|
|
Open vSwitch CI |
3f9b5c |
+ovsdb_atom_string_create_nocopy(char *str)
|
|
Open vSwitch CI |
3f9b5c |
+{
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_atom_string *s = xzalloc(sizeof *s);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ s->string = str;
|
|
Open vSwitch CI |
3f9b5c |
+ s->n_refs = 1;
|
|
Open vSwitch CI |
3f9b5c |
+ return s;
|
|
Open vSwitch CI |
3f9b5c |
+}
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+static inline struct ovsdb_atom_string *
|
|
Open vSwitch CI |
3f9b5c |
+ovsdb_atom_string_create(const char *str)
|
|
Open vSwitch CI |
3f9b5c |
+{
|
|
Open vSwitch CI |
3f9b5c |
+ return ovsdb_atom_string_create_nocopy(xstrdup(str));
|
|
Open vSwitch CI |
3f9b5c |
+}
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/* One value of an atomic type (given by enum ovs_atomic_type). */
|
|
Open vSwitch CI |
3f9b5c |
union ovsdb_atom {
|
|
Open vSwitch CI |
3f9b5c |
int64_t integer;
|
|
Open vSwitch CI |
3f9b5c |
double real;
|
|
Open vSwitch CI |
3f9b5c |
bool boolean;
|
|
Open vSwitch CI |
3f9b5c |
- char *string;
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_atom_string *s;
|
|
Open vSwitch CI |
3f9b5c |
struct uuid uuid;
|
|
Open vSwitch CI |
3f9b5c |
};
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -66,8 +88,9 @@ ovsdb_atom_needs_destruction(enum ovsdb_atomic_type type)
|
|
Open vSwitch CI |
3f9b5c |
static inline void
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_atom_destroy(union ovsdb_atom *atom, enum ovsdb_atomic_type type)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
- if (type == OVSDB_TYPE_STRING) {
|
|
Open vSwitch CI |
3f9b5c |
- free(atom->string);
|
|
Open vSwitch CI |
3f9b5c |
+ if (type == OVSDB_TYPE_STRING && !--atom->s->n_refs) {
|
|
Open vSwitch CI |
3f9b5c |
+ free(atom->s->string);
|
|
Open vSwitch CI |
3f9b5c |
+ free(atom->s);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -209,9 +232,10 @@ bool ovsdb_datum_equals(const struct ovsdb_datum *,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_type *);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* Search. */
|
|
Open vSwitch CI |
3f9b5c |
-unsigned int ovsdb_datum_find_key(const struct ovsdb_datum *,
|
|
Open vSwitch CI |
3f9b5c |
- const union ovsdb_atom *key,
|
|
Open vSwitch CI |
3f9b5c |
- enum ovsdb_atomic_type key_type);
|
|
Open vSwitch CI |
3f9b5c |
+bool ovsdb_datum_find_key(const struct ovsdb_datum *,
|
|
Open vSwitch CI |
3f9b5c |
+ const union ovsdb_atom *key,
|
|
Open vSwitch CI |
3f9b5c |
+ enum ovsdb_atomic_type key_type,
|
|
Open vSwitch CI |
3f9b5c |
+ unsigned int *pos);
|
|
Open vSwitch CI |
3f9b5c |
unsigned int ovsdb_datum_find_key_value(const struct ovsdb_datum *,
|
|
Open vSwitch CI |
3f9b5c |
const union ovsdb_atom *key,
|
|
Open vSwitch CI |
3f9b5c |
enum ovsdb_atomic_type key_type,
|
|
Open vSwitch CI |
3f9b5c |
@@ -227,14 +251,19 @@ bool ovsdb_datum_excludes_all(const struct ovsdb_datum *,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_type *);
|
|
Open vSwitch CI |
3f9b5c |
void ovsdb_datum_union(struct ovsdb_datum *,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *,
|
|
Open vSwitch CI |
3f9b5c |
- const struct ovsdb_type *,
|
|
Open vSwitch CI |
3f9b5c |
- bool replace);
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_type *);
|
|
Open vSwitch CI |
3f9b5c |
void ovsdb_datum_subtract(struct ovsdb_datum *a,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_type *a_type,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *b,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_type *b_type);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* Generate and apply diffs */
|
|
Open vSwitch CI |
3f9b5c |
+void ovsdb_datum_added_removed(struct ovsdb_datum *added,
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_datum *removed,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *old,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *new,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_type *type);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
void ovsdb_datum_diff(struct ovsdb_datum *diff,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *old_datum,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *new_datum,
|
|
Open vSwitch CI |
3f9b5c |
@@ -246,6 +275,12 @@ struct ovsdb_error *ovsdb_datum_apply_diff(struct ovsdb_datum *new_datum,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_type *type)
|
|
Open vSwitch CI |
3f9b5c |
OVS_WARN_UNUSED_RESULT;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+struct ovsdb_error * ovsdb_datum_apply_diff_in_place(
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_datum *a,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *diff,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_type *type)
|
|
Open vSwitch CI |
3f9b5c |
+OVS_WARN_UNUSED_RESULT;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/* Raw operations that may not maintain the invariants. */
|
|
Open vSwitch CI |
3f9b5c |
void ovsdb_datum_remove_unsafe(struct ovsdb_datum *, size_t idx,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_type *);
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
|
|
Open vSwitch CI |
3f9b5c |
index 2198c69c60..198ba5a828 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/lib/ovsdb-idl.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/lib/ovsdb-idl.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -1898,8 +1898,7 @@ ovsdb_idl_index_destroy_row(const struct ovsdb_idl_row *row_)
|
|
Open vSwitch CI |
3f9b5c |
BITMAP_FOR_EACH_1 (i, class->n_columns, row->written) {
|
|
Open vSwitch CI |
3f9b5c |
c = &class->columns[i];
|
|
Open vSwitch CI |
3f9b5c |
(c->unparse) (row);
|
|
Open vSwitch CI |
3f9b5c |
- free(row->new_datum[i].values);
|
|
Open vSwitch CI |
3f9b5c |
- free(row->new_datum[i].keys);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&row->new_datum[i], &c->type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
free(row->new_datum);
|
|
Open vSwitch CI |
3f9b5c |
free(row->written);
|
|
Open vSwitch CI |
3f9b5c |
@@ -2787,9 +2786,8 @@ ovsdb_idl_txn_extract_mutations(struct ovsdb_idl_row *row,
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_datum *new_datum;
|
|
Open vSwitch CI |
3f9b5c |
unsigned int pos;
|
|
Open vSwitch CI |
3f9b5c |
new_datum = map_op_datum(map_op);
|
|
Open vSwitch CI |
3f9b5c |
- pos = ovsdb_datum_find_key(old_datum,
|
|
Open vSwitch CI |
3f9b5c |
- &new_datum->keys[0],
|
|
Open vSwitch CI |
3f9b5c |
- key_type);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_find_key(old_datum, &new_datum->keys[0],
|
|
Open vSwitch CI |
3f9b5c |
+ key_type, &pos;;
|
|
Open vSwitch CI |
3f9b5c |
if (ovsdb_atom_equals(&new_datum->values[0],
|
|
Open vSwitch CI |
3f9b5c |
&old_datum->values[pos],
|
|
Open vSwitch CI |
3f9b5c |
value_type)) {
|
|
Open vSwitch CI |
3f9b5c |
@@ -2798,11 +2796,9 @@ ovsdb_idl_txn_extract_mutations(struct ovsdb_idl_row *row,
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
} else if (map_op_type(map_op) == MAP_OP_DELETE){
|
|
Open vSwitch CI |
3f9b5c |
/* Verify that there is a key to delete. */
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int pos;
|
|
Open vSwitch CI |
3f9b5c |
- pos = ovsdb_datum_find_key(old_datum,
|
|
Open vSwitch CI |
3f9b5c |
- &map_op_datum(map_op)->keys[0],
|
|
Open vSwitch CI |
3f9b5c |
- key_type);
|
|
Open vSwitch CI |
3f9b5c |
- if (pos == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_find_key(old_datum,
|
|
Open vSwitch CI |
3f9b5c |
+ &map_op_datum(map_op)->keys[0],
|
|
Open vSwitch CI |
3f9b5c |
+ key_type, NULL)) {
|
|
Open vSwitch CI |
3f9b5c |
/* No key to delete. Move on to next update. */
|
|
Open vSwitch CI |
3f9b5c |
VLOG_WARN("Trying to delete a key that doesn't "
|
|
Open vSwitch CI |
3f9b5c |
"exist in the map.");
|
|
Open vSwitch CI |
3f9b5c |
@@ -2897,11 +2893,9 @@ ovsdb_idl_txn_extract_mutations(struct ovsdb_idl_row *row,
|
|
Open vSwitch CI |
3f9b5c |
any_ins = true;
|
|
Open vSwitch CI |
3f9b5c |
} else { /* SETP_OP_DELETE */
|
|
Open vSwitch CI |
3f9b5c |
/* Verify that there is a key to delete. */
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int pos;
|
|
Open vSwitch CI |
3f9b5c |
- pos = ovsdb_datum_find_key(old_datum,
|
|
Open vSwitch CI |
3f9b5c |
- &set_op_datum(set_op)->keys[0],
|
|
Open vSwitch CI |
3f9b5c |
- key_type);
|
|
Open vSwitch CI |
3f9b5c |
- if (pos == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_find_key(old_datum,
|
|
Open vSwitch CI |
3f9b5c |
+ &set_op_datum(set_op)->keys[0],
|
|
Open vSwitch CI |
3f9b5c |
+ key_type, NULL)) {
|
|
Open vSwitch CI |
3f9b5c |
/* No key to delete. Move on to next update. */
|
|
Open vSwitch CI |
3f9b5c |
VLOG_WARN("Trying to delete a key that doesn't "
|
|
Open vSwitch CI |
3f9b5c |
"exist in the set.");
|
|
Open vSwitch CI |
3f9b5c |
@@ -4066,7 +4060,6 @@ ovsdb_idl_txn_write_partial_map(const struct ovsdb_idl_row *row_,
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_idl_row *row = CONST_CAST(struct ovsdb_idl_row *, row_);
|
|
Open vSwitch CI |
3f9b5c |
enum ovsdb_atomic_type key_type;
|
|
Open vSwitch CI |
3f9b5c |
enum map_op_type op_type;
|
|
Open vSwitch CI |
3f9b5c |
- unsigned int pos;
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *old_datum;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (!is_valid_partial_update(row, column, datum)) {
|
|
Open vSwitch CI |
3f9b5c |
@@ -4078,8 +4071,11 @@ ovsdb_idl_txn_write_partial_map(const struct ovsdb_idl_row *row_,
|
|
Open vSwitch CI |
3f9b5c |
/* Find out if this is an insert or an update. */
|
|
Open vSwitch CI |
3f9b5c |
key_type = column->type.key.type;
|
|
Open vSwitch CI |
3f9b5c |
old_datum = ovsdb_idl_read(row, column);
|
|
Open vSwitch CI |
3f9b5c |
- pos = ovsdb_datum_find_key(old_datum, &datum->keys[0], key_type);
|
|
Open vSwitch CI |
3f9b5c |
- op_type = pos == UINT_MAX ? MAP_OP_INSERT : MAP_OP_UPDATE;
|
|
Open vSwitch CI |
3f9b5c |
+ if (ovsdb_datum_find_key(old_datum, &datum->keys[0], key_type, NULL)) {
|
|
Open vSwitch CI |
3f9b5c |
+ op_type = MAP_OP_UPDATE;
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ op_type = MAP_OP_INSERT;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_add_map_op(row, column, datum, op_type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
|
110336 |
diff --git a/lib/pcap-file.c b/lib/pcap-file.c
|
|
|
110336 |
index b30a11c24b..41835f6f4d 100644
|
|
|
110336 |
--- a/lib/pcap-file.c
|
|
|
110336 |
+++ b/lib/pcap-file.c
|
|
|
110336 |
@@ -89,6 +89,7 @@ ovs_pcap_open(const char *file_name, const char *mode)
|
|
|
110336 |
: mode[0] == 'w' ? "writing"
|
|
|
110336 |
: "appending"),
|
|
|
110336 |
ovs_strerror(errno));
|
|
|
110336 |
+ free(p_file);
|
|
|
110336 |
return NULL;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
|
|
Open vSwitch CI |
3f9b5c |
index a426fcfeb6..1bab22aa5e 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/ofproto/ofproto-dpif-xlate.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ofproto/ofproto-dpif-xlate.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -6177,11 +6177,32 @@ static void
|
|
Open vSwitch CI |
3f9b5c |
compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
|
|
Open vSwitch CI |
3f9b5c |
bool is_last_action)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
- ovs_u128 old_ct_label_mask = ctx->wc->masks.ct_label;
|
|
Open vSwitch CI |
3f9b5c |
- uint32_t old_ct_mark_mask = ctx->wc->masks.ct_mark;
|
|
Open vSwitch CI |
3f9b5c |
- size_t ct_offset;
|
|
Open vSwitch CI |
3f9b5c |
uint16_t zone;
|
|
Open vSwitch CI |
3f9b5c |
+ if (ofc->zone_src.field) {
|
|
Open vSwitch CI |
3f9b5c |
+ union mf_subvalue value;
|
|
Open vSwitch CI |
3f9b5c |
+ memset(&value, 0xff, sizeof(value));
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow);
|
|
Open vSwitch CI |
3f9b5c |
+ if (ctx->xin->frozen_state) {
|
|
Open vSwitch CI |
3f9b5c |
+ /* If the upcall is a resume of a recirculation, we only need to
|
|
Open vSwitch CI |
3f9b5c |
+ * unwildcard the fields that are not in the frozen_metadata, as
|
|
Open vSwitch CI |
3f9b5c |
+ * when the rules update, OVS will generate a new recirc_id,
|
|
Open vSwitch CI |
3f9b5c |
+ * which will invalidate the megaflow with old the recirc_id.
|
|
Open vSwitch CI |
3f9b5c |
+ */
|
|
Open vSwitch CI |
3f9b5c |
+ if (!mf_is_frozen_metadata(ofc->zone_src.field)) {
|
|
Open vSwitch CI |
3f9b5c |
+ mf_write_subfield_flow(&ofc->zone_src, &value,
|
|
Open vSwitch CI |
3f9b5c |
+ &ctx->wc->masks);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ mf_write_subfield_flow(&ofc->zone_src, &value, &ctx->wc->masks);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ zone = ofc->zone_imm;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+ size_t ct_offset;
|
|
Open vSwitch CI |
3f9b5c |
+ ovs_u128 old_ct_label_mask = ctx->wc->masks.ct_label;
|
|
Open vSwitch CI |
3f9b5c |
+ uint32_t old_ct_mark_mask = ctx->wc->masks.ct_mark;
|
|
Open vSwitch CI |
3f9b5c |
/* Ensure that any prior actions are applied before composing the new
|
|
Open vSwitch CI |
3f9b5c |
* conntrack action. */
|
|
Open vSwitch CI |
3f9b5c |
xlate_commit_actions(ctx);
|
|
Open vSwitch CI |
3f9b5c |
@@ -6193,11 +6214,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
|
|
Open vSwitch CI |
3f9b5c |
do_xlate_actions(ofc->actions, ofpact_ct_get_action_len(ofc), ctx,
|
|
Open vSwitch CI |
3f9b5c |
is_last_action, false);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- if (ofc->zone_src.field) {
|
|
Open vSwitch CI |
3f9b5c |
- zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow);
|
|
Open vSwitch CI |
3f9b5c |
- } else {
|
|
Open vSwitch CI |
3f9b5c |
- zone = ofc->zone_imm;
|
|
Open vSwitch CI |
3f9b5c |
- }
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
ct_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CT);
|
|
Open vSwitch CI |
3f9b5c |
if (ofc->flags & NX_CT_F_COMMIT) {
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ovsdb/file.c b/ovsdb/file.c
|
|
Open vSwitch CI |
3f9b5c |
index 59220824fa..9f44007d97 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/ovsdb/file.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ovsdb/file.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -113,19 +113,17 @@ ovsdb_file_update_row_from_json(struct ovsdb_row *row, bool converting,
|
|
Open vSwitch CI |
3f9b5c |
if (row_contains_diff
|
|
Open vSwitch CI |
3f9b5c |
&& !ovsdb_datum_is_default(&row->fields[column->index],
|
|
Open vSwitch CI |
3f9b5c |
&column->type)) {
|
|
Open vSwitch CI |
3f9b5c |
- struct ovsdb_datum new_datum;
|
|
Open vSwitch CI |
3f9b5c |
-
|
|
Open vSwitch CI |
3f9b5c |
- error = ovsdb_datum_apply_diff(&new_datum,
|
|
Open vSwitch CI |
3f9b5c |
+ error = ovsdb_datum_apply_diff_in_place(
|
|
Open vSwitch CI |
3f9b5c |
&row->fields[column->index],
|
|
Open vSwitch CI |
3f9b5c |
&datum, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_destroy(&datum, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
if (error) {
|
|
Open vSwitch CI |
3f9b5c |
return error;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_swap(&datum, &new_datum);
|
|
Open vSwitch CI |
3f9b5c |
+ } else {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_swap(&row->fields[column->index], &datum);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&datum, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_swap(&row->fields[column->index], &datum);
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_destroy(&datum, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
return NULL;
|
|
|
110336 |
diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
|
|
|
110336 |
index 532dedcb64..ab814cf20e 100644
|
|
|
110336 |
--- a/ovsdb/monitor.c
|
|
|
110336 |
+++ b/ovsdb/monitor.c
|
|
|
110336 |
@@ -1231,6 +1231,15 @@ ovsdb_monitor_get_update(
|
|
|
110336 |
condition,
|
|
|
110336 |
ovsdb_monitor_compose_row_update2);
|
|
|
110336 |
if (!condition || !condition->conditional) {
|
|
|
110336 |
+ if (json) {
|
|
|
110336 |
+ struct json *json_serialized;
|
|
|
110336 |
+
|
|
|
110336 |
+ /* Pre-serializing the object to avoid doing this
|
|
|
110336 |
+ * for every client. */
|
|
|
110336 |
+ json_serialized = json_serialized_object_create(json);
|
|
|
110336 |
+ json_destroy(json);
|
|
|
110336 |
+ json = json_serialized;
|
|
|
110336 |
+ }
|
|
|
110336 |
ovsdb_monitor_json_cache_insert(dbmon, version, mcs,
|
|
|
110336 |
json);
|
|
|
110336 |
}
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ovsdb/mutation.c b/ovsdb/mutation.c
|
|
Open vSwitch CI |
3f9b5c |
index 56edc5f000..03d1c3499e 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/ovsdb/mutation.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ovsdb/mutation.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -383,7 +383,7 @@ ovsdb_mutation_set_execute(struct ovsdb_row *row,
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
case OVSDB_M_INSERT:
|
|
Open vSwitch CI |
3f9b5c |
- ovsdb_datum_union(dst, arg, dst_type, false);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_union(dst, arg, dst_type);
|
|
Open vSwitch CI |
3f9b5c |
error = ovsdb_mutation_check_count(dst, dst_type);
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in
|
|
Open vSwitch CI |
3f9b5c |
index 61cded16d3..78ebf2dc14 100755
|
|
Open vSwitch CI |
3f9b5c |
--- a/ovsdb/ovsdb-idlc.in
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ovsdb/ovsdb-idlc.in
|
|
Open vSwitch CI |
3f9b5c |
@@ -551,20 +551,20 @@ static void
|
|
Open vSwitch CI |
3f9b5c |
print(" smap_init(&row->%s);" % columnName)
|
|
Open vSwitch CI |
3f9b5c |
print(" for (size_t i = 0; i < datum->n; i++) {")
|
|
Open vSwitch CI |
3f9b5c |
print(" smap_add(&row->%s," % columnName)
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum->keys[i].string,")
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum->values[i].string);")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum->keys[i].s->string,")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum->values[i].s->string);")
|
|
Open vSwitch CI |
3f9b5c |
print(" }")
|
|
Open vSwitch CI |
3f9b5c |
elif (type.n_min == 1 and type.n_max == 1) or type.is_optional_pointer():
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" if (datum->n >= 1) {")
|
|
Open vSwitch CI |
3f9b5c |
if not type.key.ref_table:
|
|
Open vSwitch CI |
3f9b5c |
- print(" %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_string()))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_rvalue_string()))
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->keys[0].uuid));" % (keyVar, prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower()))
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if valueVar:
|
|
Open vSwitch CI |
3f9b5c |
if not type.value.ref_table:
|
|
Open vSwitch CI |
3f9b5c |
- print(" %s = datum->values[0].%s;" % (valueVar, type.value.type.to_string()))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" %s = datum->values[0].%s;" % (valueVar, type.value.type.to_rvalue_string()))
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->values[0].uuid));" % (valueVar, prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower()))
|
|
Open vSwitch CI |
3f9b5c |
print(" } else {")
|
|
Open vSwitch CI |
3f9b5c |
@@ -592,7 +592,7 @@ static void
|
|
Open vSwitch CI |
3f9b5c |
""" % (prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower()))
|
|
Open vSwitch CI |
3f9b5c |
keySrc = "keyRow"
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
- keySrc = "datum->keys[i].%s" % type.key.type.to_string()
|
|
Open vSwitch CI |
3f9b5c |
+ keySrc = "datum->keys[i].%s" % type.key.type.to_rvalue_string()
|
|
Open vSwitch CI |
3f9b5c |
if type.value and type.value.ref_table:
|
|
Open vSwitch CI |
3f9b5c |
print("""\
|
|
Open vSwitch CI |
3f9b5c |
struct %s%s *valueRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->values[i].uuid));
|
|
Open vSwitch CI |
3f9b5c |
@@ -602,7 +602,7 @@ static void
|
|
Open vSwitch CI |
3f9b5c |
""" % (prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower()))
|
|
Open vSwitch CI |
3f9b5c |
valueSrc = "valueRow"
|
|
Open vSwitch CI |
3f9b5c |
elif valueVar:
|
|
Open vSwitch CI |
3f9b5c |
- valueSrc = "datum->values[i].%s" % type.value.type.to_string()
|
|
Open vSwitch CI |
3f9b5c |
+ valueSrc = "datum->values[i].%s" % type.value.type.to_rvalue_string()
|
|
Open vSwitch CI |
3f9b5c |
print(" if (!row->n_%s) {" % (columnName))
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
print(" %s = xmalloc(%s * sizeof *%s);" % (
|
|
Open vSwitch CI |
3f9b5c |
@@ -910,45 +910,45 @@ void
|
|
Open vSwitch CI |
3f9b5c |
'args': ', '.join(['%(type)s%(name)s'
|
|
Open vSwitch CI |
3f9b5c |
% m for m in members])})
|
|
Open vSwitch CI |
3f9b5c |
if type.n_min == 1 and type.n_max == 1:
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom value;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *value = xmalloc(sizeof *value);")
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.keys = &ke;;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.values = &value;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum.values = value;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.value.copyCValue("value->%s" % type.value.type.to_lvalue_string(), valueVar))
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
- txn_write_func = "ovsdb_idl_txn_write_clone"
|
|
Open vSwitch CI |
3f9b5c |
+ txn_write_func = "ovsdb_idl_txn_write"
|
|
Open vSwitch CI |
3f9b5c |
elif type.is_optional_pointer():
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom key;")
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" if (%s) {" % keyVar)
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.keys = &ke;;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
print(" } else {")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 0;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
print(" }")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
- txn_write_func = "ovsdb_idl_txn_write_clone"
|
|
Open vSwitch CI |
3f9b5c |
+ txn_write_func = "ovsdb_idl_txn_write"
|
|
Open vSwitch CI |
3f9b5c |
elif type.n_max == 1:
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom key;")
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" if (%s) {" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.keys = &ke;;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), "*" + keyVar))
|
|
Open vSwitch CI |
3f9b5c |
print(" } else {")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 0;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
print(" }")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
- txn_write_func = "ovsdb_idl_txn_write_clone"
|
|
Open vSwitch CI |
3f9b5c |
+ txn_write_func = "ovsdb_idl_txn_write"
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = %s;" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
@@ -958,9 +958,9 @@ void
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
print(" for (size_t i = 0; i < %s; i++) {" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_lvalue_string(), "%s[i]" % keyVar))
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_lvalue_string(), "%s[i]" % valueVar))
|
|
Open vSwitch CI |
3f9b5c |
print(" }")
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
valueType = type.value.toAtomicType()
|
|
Open vSwitch CI |
3f9b5c |
@@ -996,9 +996,8 @@ void
|
|
Open vSwitch CI |
3f9b5c |
''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
|
|
Open vSwitch CI |
3f9b5c |
'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
|
|
Open vSwitch CI |
3f9b5c |
'C': columnName.upper(), 't': tableName})
|
|
Open vSwitch CI |
3f9b5c |
-
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "new_key"))
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.value.copyCValue("datum->values[0].%s" % type.value.type.to_string(), "new_value"))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_lvalue_string(), "new_key"))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.value.copyCValue("datum->values[0].%s" % type.value.type.to_lvalue_string(), "new_value"))
|
|
Open vSwitch CI |
3f9b5c |
print('''
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_write_partial_map(&row->header_,
|
|
Open vSwitch CI |
3f9b5c |
&%(s)s_col_%(c)s,
|
|
Open vSwitch CI |
3f9b5c |
@@ -1022,8 +1021,7 @@ void
|
|
Open vSwitch CI |
3f9b5c |
''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
|
|
Open vSwitch CI |
3f9b5c |
'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
|
|
Open vSwitch CI |
3f9b5c |
'C': columnName.upper(), 't': tableName})
|
|
Open vSwitch CI |
3f9b5c |
-
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "delete_key"))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_lvalue_string(), "delete_key"))
|
|
Open vSwitch CI |
3f9b5c |
print('''
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_delete_partial_map(&row->header_,
|
|
Open vSwitch CI |
3f9b5c |
&%(s)s_col_%(c)s,
|
|
Open vSwitch CI |
3f9b5c |
@@ -1049,8 +1047,7 @@ void
|
|
Open vSwitch CI |
3f9b5c |
datum->values = NULL;
|
|
Open vSwitch CI |
3f9b5c |
''' % {'s': structName, 'c': columnName,
|
|
Open vSwitch CI |
3f9b5c |
'valtype':column.type.key.to_const_c_type(prefix), 't': tableName})
|
|
Open vSwitch CI |
3f9b5c |
-
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "new_value"))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_lvalue_string(), "new_value"))
|
|
Open vSwitch CI |
3f9b5c |
print('''
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_write_partial_set(&row->header_,
|
|
Open vSwitch CI |
3f9b5c |
&%(s)s_col_%(c)s,
|
|
Open vSwitch CI |
3f9b5c |
@@ -1074,8 +1071,7 @@ void
|
|
Open vSwitch CI |
3f9b5c |
''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
|
|
Open vSwitch CI |
3f9b5c |
'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper(),
|
|
Open vSwitch CI |
3f9b5c |
'C': columnName.upper(), 't': tableName})
|
|
Open vSwitch CI |
3f9b5c |
-
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "delete_value"))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_lvalue_string(), "delete_value"))
|
|
Open vSwitch CI |
3f9b5c |
print('''
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_delete_partial_set(&row->header_,
|
|
Open vSwitch CI |
3f9b5c |
&%(s)s_col_%(c)s,
|
|
Open vSwitch CI |
3f9b5c |
@@ -1143,37 +1139,36 @@ void
|
|
Open vSwitch CI |
3f9b5c |
print(" struct ovsdb_datum datum;")
|
|
Open vSwitch CI |
3f9b5c |
free = []
|
|
Open vSwitch CI |
3f9b5c |
if type.n_min == 1 and type.n_max == 1:
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom value;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *value = xmalloc(sizeof *value);")
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.keys = &ke;;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.values = &value;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.value.copyCValue("value.%s" % type.value.type.to_lvalue_string(), valueVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
elif type.is_optional_pointer():
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom key;")
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" if (%s) {" % keyVar)
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.keys = &ke;;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
print(" } else {")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 0;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
print(" }")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
elif type.n_max == 1:
|
|
Open vSwitch CI |
3f9b5c |
- print(" union ovsdb_atom key;")
|
|
Open vSwitch CI |
3f9b5c |
print("")
|
|
Open vSwitch CI |
3f9b5c |
print(" if (%s) {" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
+ print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" datum.keys = &ke;;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), "*" + keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
print(" } else {")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 0;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
@@ -1182,16 +1177,14 @@ void
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = %s;" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar))
|
|
Open vSwitch CI |
3f9b5c |
- free += ['datum.keys']
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = xmalloc(%s * sizeof *datum.values);" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
- free += ['datum.values']
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
print(" for (size_t i = 0; i < %s; i++) {" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_lvalue_string(), "%s[i]" % keyVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.value.assign_c_value_casting_away_const("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_lvalue_string(), "%s[i]" % valueVar, refTable=False))
|
|
Open vSwitch CI |
3f9b5c |
print(" }")
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
valueType = type.value.toAtomicType()
|
|
Open vSwitch CI |
3f9b5c |
@@ -1211,8 +1204,8 @@ void
|
|
Open vSwitch CI |
3f9b5c |
's': structName,
|
|
Open vSwitch CI |
3f9b5c |
'S': structName.upper(),
|
|
Open vSwitch CI |
3f9b5c |
'c': columnName})
|
|
Open vSwitch CI |
3f9b5c |
- for var in free:
|
|
Open vSwitch CI |
3f9b5c |
- print(" free(%s);" % var)
|
|
Open vSwitch CI |
3f9b5c |
+ print(" ovsdb_datum_destroy(&datum, &%(s)s_col_%(c)s.type);" \
|
|
Open vSwitch CI |
3f9b5c |
+ % {'s': structName, 'c': columnName})
|
|
Open vSwitch CI |
3f9b5c |
print("}")
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
# Index table related functions
|
|
Open vSwitch CI |
3f9b5c |
@@ -1309,8 +1302,8 @@ struct %(s)s *
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
i = 0;
|
|
Open vSwitch CI |
3f9b5c |
SMAP_FOR_EACH (node, %(c)s) {
|
|
Open vSwitch CI |
3f9b5c |
- datum->keys[i].string = node->key;
|
|
Open vSwitch CI |
3f9b5c |
- datum->values[i].string = node->value;
|
|
Open vSwitch CI |
3f9b5c |
+ datum->keys[i].s = ovsdb_atom_string_create(node->key);
|
|
Open vSwitch CI |
3f9b5c |
+ datum->values[i].s = ovsdb_atom_string_create(node->value);
|
|
Open vSwitch CI |
3f9b5c |
i++;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_sort_unique(datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
@@ -1359,10 +1352,10 @@ struct %(s)s *
|
|
Open vSwitch CI |
3f9b5c |
print()
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key->%s" % type.key.type.to_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = value;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" "+ type.value.assign_c_value_casting_away_const("value->%s" % type.value.type.to_string(), valueVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.value.copyCValue("value->%s" % type.value.type.to_lvalue_string(), valueVar))
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
txn_write_func = "ovsdb_idl_index_write"
|
|
Open vSwitch CI |
3f9b5c |
@@ -1373,7 +1366,7 @@ struct %(s)s *
|
|
Open vSwitch CI |
3f9b5c |
print(" key = xmalloc(sizeof (union ovsdb_atom));")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key->%s" % type.key.type.to_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), keyVar))
|
|
Open vSwitch CI |
3f9b5c |
print(" } else {")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 0;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
@@ -1387,7 +1380,7 @@ struct %(s)s *
|
|
Open vSwitch CI |
3f9b5c |
print(" key = xmalloc(sizeof(union ovsdb_atom));")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 1;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = key;")
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.assign_c_value_casting_away_const("key->%s" % type.key.type.to_string(), "*" + keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("key->%s" % type.key.type.to_lvalue_string(), "*" + keyVar))
|
|
Open vSwitch CI |
3f9b5c |
print(" } else {")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.n = 0;")
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.keys = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
@@ -1404,9 +1397,9 @@ struct %(s)s *
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
print(" datum.values = NULL;")
|
|
Open vSwitch CI |
3f9b5c |
print(" for (i = 0; i < %s; i++) {" % nVar)
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_lvalue_string(), "%s[i]" % keyVar))
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
- print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar))
|
|
Open vSwitch CI |
3f9b5c |
+ print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_lvalue_string(), "%s[i]" % valueVar))
|
|
Open vSwitch CI |
3f9b5c |
print(" }")
|
|
Open vSwitch CI |
3f9b5c |
if type.value:
|
|
Open vSwitch CI |
3f9b5c |
valueType = type.value.toAtomicType()
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
|
|
Open vSwitch CI |
3f9b5c |
index 0b3d2bb714..b34d97e291 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/ovsdb/ovsdb-server.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ovsdb/ovsdb-server.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -904,8 +904,8 @@ query_db_string(const struct shash *all_dbs, const char *name,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
datum = &row->fields[column->index];
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < datum->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
- if (datum->keys[i].string[0]) {
|
|
Open vSwitch CI |
3f9b5c |
- return datum->keys[i].string;
|
|
Open vSwitch CI |
3f9b5c |
+ if (datum->keys[i].s->string[0]) {
|
|
Open vSwitch CI |
3f9b5c |
+ return datum->keys[i].s->string;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
@@ -1018,7 +1018,7 @@ query_db_remotes(const char *name, const struct shash *all_dbs,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
datum = &row->fields[column->index];
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < datum->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
- add_remote(remotes, datum->keys[i].string);
|
|
Open vSwitch CI |
3f9b5c |
+ add_remote(remotes, datum->keys[i].s->string);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
} else if (column->type.key.type == OVSDB_TYPE_UUID
|
|
|
110336 |
diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c
|
|
|
110336 |
index 05a0223e71..d4a9e34cc4 100644
|
|
|
110336 |
--- a/ovsdb/ovsdb-tool.c
|
|
|
110336 |
+++ b/ovsdb/ovsdb-tool.c
|
|
|
110336 |
@@ -919,7 +919,8 @@ print_raft_header(const struct raft_header *h,
|
|
|
110336 |
if (!uuid_is_zero(&h->snap.eid)) {
|
|
|
110336 |
printf(" prev_eid: %04x\n", uuid_prefix(&h->snap.eid, 4));
|
|
|
110336 |
}
|
|
|
110336 |
- print_data("prev_", h->snap.data, schemap, names);
|
|
|
110336 |
+ print_data("prev_", raft_entry_get_parsed_data(&h->snap),
|
|
|
110336 |
+ schemap, names);
|
|
|
110336 |
}
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
@@ -973,11 +974,13 @@ raft_header_to_standalone_log(const struct raft_header *h,
|
|
|
110336 |
struct ovsdb_log *db_log_data)
|
|
|
110336 |
{
|
|
|
110336 |
if (h->snap_index) {
|
|
|
110336 |
- if (!h->snap.data || json_array(h->snap.data)->n != 2) {
|
|
|
110336 |
+ const struct json *data = raft_entry_get_parsed_data(&h->snap);
|
|
|
110336 |
+
|
|
|
110336 |
+ if (!data || json_array(data)->n != 2) {
|
|
|
110336 |
ovs_fatal(0, "Incorrect raft header data array length");
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
- struct json_array *pa = json_array(h->snap.data);
|
|
|
110336 |
+ struct json_array *pa = json_array(data);
|
|
|
110336 |
struct json *schema_json = pa->elems[0];
|
|
|
110336 |
struct ovsdb_error *error = NULL;
|
|
|
110336 |
|
|
|
110336 |
@@ -1373,7 +1376,7 @@ do_check_cluster(struct ovs_cmdl_context *ctx)
|
|
|
110336 |
}
|
|
|
110336 |
struct raft_entry *e = &s->entries[log_idx];
|
|
|
110336 |
e->term = r->term;
|
|
|
110336 |
- e->data = r->entry.data;
|
|
|
110336 |
+ raft_entry_set_parsed_data_nocopy(e, r->entry.data);
|
|
|
110336 |
e->eid = r->entry.eid;
|
|
|
110336 |
e->servers = r->entry.servers;
|
|
|
110336 |
break;
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ovsdb/ovsdb-util.c b/ovsdb/ovsdb-util.c
|
|
Open vSwitch CI |
3f9b5c |
index c4075cdae3..6d7be066b6 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/ovsdb/ovsdb-util.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ovsdb/ovsdb-util.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -111,13 +111,13 @@ ovsdb_util_read_map_string_column(const struct ovsdb_row *row,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < datum->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
atom_key = &datum->keys[i];
|
|
Open vSwitch CI |
3f9b5c |
- if (!strcmp(atom_key->string, key)) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!strcmp(atom_key->s->string, key)) {
|
|
Open vSwitch CI |
3f9b5c |
atom_value = &datum->values[i];
|
|
Open vSwitch CI |
3f9b5c |
break;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- return atom_value ? atom_value->string : NULL;
|
|
Open vSwitch CI |
3f9b5c |
+ return atom_value ? atom_value->s->string : NULL;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* Read string-uuid key-values from a map. Returns the row associated with
|
|
Open vSwitch CI |
3f9b5c |
@@ -143,7 +143,7 @@ ovsdb_util_read_map_string_uuid_column(const struct ovsdb_row *row,
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *datum = &row->fields[column->index];
|
|
Open vSwitch CI |
3f9b5c |
for (size_t i = 0; i < datum->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
union ovsdb_atom *atom_key = &datum->keys[i];
|
|
Open vSwitch CI |
3f9b5c |
- if (!strcmp(atom_key->string, key)) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!strcmp(atom_key->s->string, key)) {
|
|
Open vSwitch CI |
3f9b5c |
const union ovsdb_atom *atom_value = &datum->values[i];
|
|
Open vSwitch CI |
3f9b5c |
return ovsdb_table_get_row(ref_table, &atom_value->uuid);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
@@ -181,7 +181,7 @@ ovsdb_util_read_string_column(const struct ovsdb_row *row,
|
|
Open vSwitch CI |
3f9b5c |
const union ovsdb_atom *atom;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
atom = ovsdb_util_read_column(row, column_name, OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
- *stringp = atom ? atom->string : NULL;
|
|
Open vSwitch CI |
3f9b5c |
+ *stringp = atom ? atom->s->string : NULL;
|
|
Open vSwitch CI |
3f9b5c |
return atom != NULL;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -269,8 +269,10 @@ ovsdb_util_write_string_column(struct ovsdb_row *row, const char *column_name,
|
|
Open vSwitch CI |
3f9b5c |
const char *string)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
if (string) {
|
|
Open vSwitch CI |
3f9b5c |
- const union ovsdb_atom atom = { .string = CONST_CAST(char *, string) };
|
|
Open vSwitch CI |
3f9b5c |
+ union ovsdb_atom atom = {
|
|
Open vSwitch CI |
3f9b5c |
+ .s = ovsdb_atom_string_create(CONST_CAST(char *, string)) };
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_util_write_singleton(row, column_name, &atom, OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_atom_destroy(&atom, OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
} else {
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_util_clear_column(row, column_name);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
@@ -305,8 +307,8 @@ ovsdb_util_write_string_string_column(struct ovsdb_row *row,
|
|
Open vSwitch CI |
3f9b5c |
datum->values = xmalloc(n * sizeof *datum->values);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < n; ++i) {
|
|
Open vSwitch CI |
3f9b5c |
- datum->keys[i].string = keys[i];
|
|
Open vSwitch CI |
3f9b5c |
- datum->values[i].string = values[i];
|
|
Open vSwitch CI |
3f9b5c |
+ datum->keys[i].s = ovsdb_atom_string_create_nocopy(keys[i]);
|
|
Open vSwitch CI |
3f9b5c |
+ datum->values[i].s = ovsdb_atom_string_create_nocopy(values[i]);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
/* Sort and check constraints. */
|
|
|
110336 |
diff --git a/ovsdb/raft-private.c b/ovsdb/raft-private.c
|
|
|
110336 |
index 26d39a087f..30760233ee 100644
|
|
|
110336 |
--- a/ovsdb/raft-private.c
|
|
|
110336 |
+++ b/ovsdb/raft-private.c
|
|
|
110336 |
@@ -18,11 +18,14 @@
|
|
|
110336 |
|
|
|
110336 |
#include "raft-private.h"
|
|
|
110336 |
|
|
|
110336 |
+#include "coverage.h"
|
|
|
110336 |
#include "openvswitch/dynamic-string.h"
|
|
|
110336 |
#include "ovsdb-error.h"
|
|
|
110336 |
#include "ovsdb-parser.h"
|
|
|
110336 |
#include "socket-util.h"
|
|
|
110336 |
#include "sset.h"
|
|
|
110336 |
+
|
|
|
110336 |
+COVERAGE_DEFINE(raft_entry_serialize);
|
|
|
110336 |
|
|
|
110336 |
/* Addresses of Raft servers. */
|
|
|
110336 |
|
|
|
110336 |
@@ -281,7 +284,8 @@ void
|
|
|
110336 |
raft_entry_clone(struct raft_entry *dst, const struct raft_entry *src)
|
|
|
110336 |
{
|
|
|
110336 |
dst->term = src->term;
|
|
|
110336 |
- dst->data = json_nullable_clone(src->data);
|
|
|
110336 |
+ dst->data.full_json = json_nullable_clone(src->data.full_json);
|
|
|
110336 |
+ dst->data.serialized = json_nullable_clone(src->data.serialized);
|
|
|
110336 |
dst->eid = src->eid;
|
|
|
110336 |
dst->servers = json_nullable_clone(src->servers);
|
|
|
110336 |
dst->election_timer = src->election_timer;
|
|
|
110336 |
@@ -291,7 +295,8 @@ void
|
|
|
110336 |
raft_entry_uninit(struct raft_entry *e)
|
|
|
110336 |
{
|
|
|
110336 |
if (e) {
|
|
|
110336 |
- json_destroy(e->data);
|
|
|
110336 |
+ json_destroy(e->data.full_json);
|
|
|
110336 |
+ json_destroy(e->data.serialized);
|
|
|
110336 |
json_destroy(e->servers);
|
|
|
110336 |
}
|
|
|
110336 |
}
|
|
|
110336 |
@@ -301,8 +306,9 @@ raft_entry_to_json(const struct raft_entry *e)
|
|
|
110336 |
{
|
|
|
110336 |
struct json *json = json_object_create();
|
|
|
110336 |
raft_put_uint64(json, "term", e->term);
|
|
|
110336 |
- if (e->data) {
|
|
|
110336 |
- json_object_put(json, "data", json_clone(e->data));
|
|
|
110336 |
+ if (raft_entry_has_data(e)) {
|
|
|
110336 |
+ json_object_put(json, "data",
|
|
|
110336 |
+ json_clone(raft_entry_get_serialized_data(e)));
|
|
|
110336 |
json_object_put_format(json, "eid", UUID_FMT, UUID_ARGS(&e->eid));
|
|
|
110336 |
}
|
|
|
110336 |
if (e->servers) {
|
|
|
110336 |
@@ -323,9 +329,10 @@ raft_entry_from_json(struct json *json, struct raft_entry *e)
|
|
|
110336 |
struct ovsdb_parser p;
|
|
|
110336 |
ovsdb_parser_init(&p, json, "raft log entry");
|
|
|
110336 |
e->term = raft_parse_required_uint64(&p, "term");
|
|
|
110336 |
- e->data = json_nullable_clone(
|
|
|
110336 |
+ raft_entry_set_parsed_data(e,
|
|
|
110336 |
ovsdb_parser_member(&p, "data", OP_OBJECT | OP_ARRAY | OP_OPTIONAL));
|
|
|
110336 |
- e->eid = e->data ? raft_parse_required_uuid(&p, "eid") : UUID_ZERO;
|
|
|
110336 |
+ e->eid = raft_entry_has_data(e)
|
|
|
110336 |
+ ? raft_parse_required_uuid(&p, "eid") : UUID_ZERO;
|
|
|
110336 |
e->servers = json_nullable_clone(
|
|
|
110336 |
ovsdb_parser_member(&p, "servers", OP_OBJECT | OP_OPTIONAL));
|
|
|
110336 |
if (e->servers) {
|
|
|
110336 |
@@ -344,9 +351,72 @@ bool
|
|
|
110336 |
raft_entry_equals(const struct raft_entry *a, const struct raft_entry *b)
|
|
|
110336 |
{
|
|
|
110336 |
return (a->term == b->term
|
|
|
110336 |
- && json_equal(a->data, b->data)
|
|
|
110336 |
&& uuid_equals(&a->eid, &b->eid)
|
|
|
110336 |
- && json_equal(a->servers, b->servers));
|
|
|
110336 |
+ && json_equal(a->servers, b->servers)
|
|
|
110336 |
+ && json_equal(raft_entry_get_parsed_data(a),
|
|
|
110336 |
+ raft_entry_get_parsed_data(b)));
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+bool
|
|
|
110336 |
+raft_entry_has_data(const struct raft_entry *e)
|
|
|
110336 |
+{
|
|
|
110336 |
+ return e->data.full_json || e->data.serialized;
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+static void
|
|
|
110336 |
+raft_entry_data_serialize(struct raft_entry *e)
|
|
|
110336 |
+{
|
|
|
110336 |
+ if (!raft_entry_has_data(e) || e->data.serialized) {
|
|
|
110336 |
+ return;
|
|
|
110336 |
+ }
|
|
|
110336 |
+ COVERAGE_INC(raft_entry_serialize);
|
|
|
110336 |
+ e->data.serialized = json_serialized_object_create(e->data.full_json);
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+void
|
|
|
110336 |
+raft_entry_set_parsed_data_nocopy(struct raft_entry *e, struct json *json)
|
|
|
110336 |
+{
|
|
|
110336 |
+ ovs_assert(!json || json->type != JSON_SERIALIZED_OBJECT);
|
|
|
110336 |
+ e->data.full_json = json;
|
|
|
110336 |
+ e->data.serialized = NULL;
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+void
|
|
|
110336 |
+raft_entry_set_parsed_data(struct raft_entry *e, const struct json *json)
|
|
|
110336 |
+{
|
|
|
110336 |
+ raft_entry_set_parsed_data_nocopy(e, json_nullable_clone(json));
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+/* Returns a pointer to the fully parsed json object of the data.
|
|
|
110336 |
+ * Caller takes the ownership of the result.
|
|
|
110336 |
+ *
|
|
|
110336 |
+ * Entry will no longer contain a fully parsed json object.
|
|
|
110336 |
+ * Subsequent calls for the same raft entry will return NULL. */
|
|
|
110336 |
+struct json * OVS_WARN_UNUSED_RESULT
|
|
|
110336 |
+raft_entry_steal_parsed_data(struct raft_entry *e)
|
|
|
110336 |
+{
|
|
|
110336 |
+ /* Ensure that serialized version exists. */
|
|
|
110336 |
+ raft_entry_data_serialize(e);
|
|
|
110336 |
+
|
|
|
110336 |
+ struct json *json = e->data.full_json;
|
|
|
110336 |
+ e->data.full_json = NULL;
|
|
|
110336 |
+
|
|
|
110336 |
+ return json;
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+/* Returns a pointer to the fully parsed json object of the data, if any. */
|
|
|
110336 |
+const struct json *
|
|
|
110336 |
+raft_entry_get_parsed_data(const struct raft_entry *e)
|
|
|
110336 |
+{
|
|
|
110336 |
+ return e->data.full_json;
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+/* Returns a pointer to the JSON_SERIALIZED_OBJECT of the data. */
|
|
|
110336 |
+const struct json *
|
|
|
110336 |
+raft_entry_get_serialized_data(const struct raft_entry *e)
|
|
|
110336 |
+{
|
|
|
110336 |
+ raft_entry_data_serialize(CONST_CAST(struct raft_entry *, e));
|
|
|
110336 |
+ return e->data.serialized;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
void
|
|
|
110336 |
@@ -402,8 +472,8 @@ raft_header_from_json__(struct raft_header *h, struct ovsdb_parser *p)
|
|
|
110336 |
* present, all of them must be. */
|
|
|
110336 |
h->snap_index = raft_parse_optional_uint64(p, "prev_index");
|
|
|
110336 |
if (h->snap_index) {
|
|
|
110336 |
- h->snap.data = json_nullable_clone(
|
|
|
110336 |
- ovsdb_parser_member(p, "prev_data", OP_ANY));
|
|
|
110336 |
+ raft_entry_set_parsed_data(
|
|
|
110336 |
+ &h->snap, ovsdb_parser_member(p, "prev_data", OP_ANY));
|
|
|
110336 |
h->snap.eid = raft_parse_required_uuid(p, "prev_eid");
|
|
|
110336 |
h->snap.term = raft_parse_required_uint64(p, "prev_term");
|
|
|
110336 |
h->snap.election_timer = raft_parse_optional_uint64(
|
|
|
110336 |
@@ -455,8 +525,9 @@ raft_header_to_json(const struct raft_header *h)
|
|
|
110336 |
if (h->snap_index) {
|
|
|
110336 |
raft_put_uint64(json, "prev_index", h->snap_index);
|
|
|
110336 |
raft_put_uint64(json, "prev_term", h->snap.term);
|
|
|
110336 |
- if (h->snap.data) {
|
|
|
110336 |
- json_object_put(json, "prev_data", json_clone(h->snap.data));
|
|
|
110336 |
+ if (raft_entry_has_data(&h->snap)) {
|
|
|
110336 |
+ json_object_put(json, "prev_data",
|
|
|
110336 |
+ json_clone(raft_entry_get_serialized_data(&h->snap)));
|
|
|
110336 |
}
|
|
|
110336 |
json_object_put_format(json, "prev_eid",
|
|
|
110336 |
UUID_FMT, UUID_ARGS(&h->snap.eid));
|
|
|
110336 |
diff --git a/ovsdb/raft-private.h b/ovsdb/raft-private.h
|
|
|
110336 |
index a69e37e5c2..48c6df511f 100644
|
|
|
110336 |
--- a/ovsdb/raft-private.h
|
|
|
110336 |
+++ b/ovsdb/raft-private.h
|
|
|
110336 |
@@ -118,7 +118,10 @@ void raft_servers_format(const struct hmap *servers, struct ds *ds);
|
|
|
110336 |
* entry. */
|
|
|
110336 |
struct raft_entry {
|
|
|
110336 |
uint64_t term;
|
|
|
110336 |
- struct json *data;
|
|
|
110336 |
+ struct {
|
|
|
110336 |
+ struct json *full_json; /* Fully parsed JSON object. */
|
|
|
110336 |
+ struct json *serialized; /* JSON_SERIALIZED_OBJECT version of data. */
|
|
|
110336 |
+ } data;
|
|
|
110336 |
struct uuid eid;
|
|
|
110336 |
struct json *servers;
|
|
|
110336 |
uint64_t election_timer;
|
|
|
110336 |
@@ -130,6 +133,13 @@ struct json *raft_entry_to_json(const struct raft_entry *);
|
|
|
110336 |
struct ovsdb_error *raft_entry_from_json(struct json *, struct raft_entry *)
|
|
|
110336 |
OVS_WARN_UNUSED_RESULT;
|
|
|
110336 |
bool raft_entry_equals(const struct raft_entry *, const struct raft_entry *);
|
|
|
110336 |
+bool raft_entry_has_data(const struct raft_entry *);
|
|
|
110336 |
+void raft_entry_set_parsed_data(struct raft_entry *, const struct json *);
|
|
|
110336 |
+void raft_entry_set_parsed_data_nocopy(struct raft_entry *, struct json *);
|
|
|
110336 |
+struct json *raft_entry_steal_parsed_data(struct raft_entry *)
|
|
|
110336 |
+ OVS_WARN_UNUSED_RESULT;
|
|
|
110336 |
+const struct json *raft_entry_get_parsed_data(const struct raft_entry *);
|
|
|
110336 |
+const struct json *raft_entry_get_serialized_data(const struct raft_entry *);
|
|
|
110336 |
|
|
|
110336 |
/* On disk data serialization and deserialization. */
|
|
|
110336 |
|
|
|
110336 |
diff --git a/ovsdb/raft.c b/ovsdb/raft.c
|
|
|
110336 |
index 2fb5156519..ce40c5bc07 100644
|
|
|
110336 |
--- a/ovsdb/raft.c
|
|
|
110336 |
+++ b/ovsdb/raft.c
|
|
|
110336 |
@@ -494,11 +494,11 @@ raft_create_cluster(const char *file_name, const char *name,
|
|
|
110336 |
.snap_index = index++,
|
|
|
110336 |
.snap = {
|
|
|
110336 |
.term = term,
|
|
|
110336 |
- .data = json_nullable_clone(data),
|
|
|
110336 |
.eid = uuid_random(),
|
|
|
110336 |
.servers = json_object_create(),
|
|
|
110336 |
},
|
|
|
110336 |
};
|
|
|
110336 |
+ raft_entry_set_parsed_data(&h.snap, data);
|
|
|
110336 |
shash_add_nocopy(json_object(h.snap.servers),
|
|
|
110336 |
xasprintf(UUID_FMT, UUID_ARGS(&h.sid)),
|
|
|
110336 |
json_string_create(local_address));
|
|
|
110336 |
@@ -727,10 +727,10 @@ raft_add_entry(struct raft *raft,
|
|
|
110336 |
uint64_t index = raft->log_end++;
|
|
|
110336 |
struct raft_entry *entry = &raft->entries[index - raft->log_start];
|
|
|
110336 |
entry->term = term;
|
|
|
110336 |
- entry->data = data;
|
|
|
110336 |
entry->eid = eid ? *eid : UUID_ZERO;
|
|
|
110336 |
entry->servers = servers;
|
|
|
110336 |
entry->election_timer = election_timer;
|
|
|
110336 |
+ raft_entry_set_parsed_data_nocopy(entry, data);
|
|
|
110336 |
return index;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
@@ -741,13 +741,16 @@ raft_write_entry(struct raft *raft, uint64_t term, struct json *data,
|
|
|
110336 |
const struct uuid *eid, struct json *servers,
|
|
|
110336 |
uint64_t election_timer)
|
|
|
110336 |
{
|
|
|
110336 |
+ uint64_t index = raft_add_entry(raft, term, data, eid, servers,
|
|
|
110336 |
+ election_timer);
|
|
|
110336 |
+ const struct json *entry_data = raft_entry_get_serialized_data(
|
|
|
110336 |
+ &raft->entries[index - raft->log_start]);
|
|
|
110336 |
struct raft_record r = {
|
|
|
110336 |
.type = RAFT_REC_ENTRY,
|
|
|
110336 |
.term = term,
|
|
|
110336 |
.entry = {
|
|
|
110336 |
- .index = raft_add_entry(raft, term, data, eid, servers,
|
|
|
110336 |
- election_timer),
|
|
|
110336 |
- .data = data,
|
|
|
110336 |
+ .index = index,
|
|
|
110336 |
+ .data = CONST_CAST(struct json *, entry_data),
|
|
|
110336 |
.servers = servers,
|
|
|
110336 |
.election_timer = election_timer,
|
|
|
110336 |
.eid = eid ? *eid : UUID_ZERO,
|
|
|
110336 |
@@ -2161,7 +2164,7 @@ raft_get_eid(const struct raft *raft, uint64_t index)
|
|
|
110336 |
{
|
|
|
110336 |
for (; index >= raft->log_start; index--) {
|
|
|
110336 |
const struct raft_entry *e = raft_get_entry(raft, index);
|
|
|
110336 |
- if (e->data) {
|
|
|
110336 |
+ if (raft_entry_has_data(e)) {
|
|
|
110336 |
return &e->eid;
|
|
|
110336 |
}
|
|
|
110336 |
}
|
|
|
110336 |
@@ -2826,8 +2829,8 @@ raft_truncate(struct raft *raft, uint64_t new_end)
|
|
|
110336 |
return servers_changed;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
-static const struct json *
|
|
|
110336 |
-raft_peek_next_entry(struct raft *raft, struct uuid *eid)
|
|
|
110336 |
+static const struct raft_entry *
|
|
|
110336 |
+raft_peek_next_entry(struct raft *raft)
|
|
|
110336 |
{
|
|
|
110336 |
/* Invariant: log_start - 2 <= last_applied <= commit_index < log_end. */
|
|
|
110336 |
ovs_assert(raft->log_start <= raft->last_applied + 2);
|
|
|
110336 |
@@ -2839,32 +2842,20 @@ raft_peek_next_entry(struct raft *raft, struct uuid *eid)
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
if (raft->log_start == raft->last_applied + 2) {
|
|
|
110336 |
- *eid = raft->snap.eid;
|
|
|
110336 |
- return raft->snap.data;
|
|
|
110336 |
+ return &raft->snap;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
while (raft->last_applied < raft->commit_index) {
|
|
|
110336 |
const struct raft_entry *e = raft_get_entry(raft,
|
|
|
110336 |
raft->last_applied + 1);
|
|
|
110336 |
- if (e->data) {
|
|
|
110336 |
- *eid = e->eid;
|
|
|
110336 |
- return e->data;
|
|
|
110336 |
+ if (raft_entry_has_data(e)) {
|
|
|
110336 |
+ return e;
|
|
|
110336 |
}
|
|
|
110336 |
raft->last_applied++;
|
|
|
110336 |
}
|
|
|
110336 |
return NULL;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
-static const struct json *
|
|
|
110336 |
-raft_get_next_entry(struct raft *raft, struct uuid *eid)
|
|
|
110336 |
-{
|
|
|
110336 |
- const struct json *data = raft_peek_next_entry(raft, eid);
|
|
|
110336 |
- if (data) {
|
|
|
110336 |
- raft->last_applied++;
|
|
|
110336 |
- }
|
|
|
110336 |
- return data;
|
|
|
110336 |
-}
|
|
|
110336 |
-
|
|
|
110336 |
/* Updates commit index in raft log. If commit index is already up-to-date
|
|
|
110336 |
* it does nothing and return false, otherwise, returns true. */
|
|
|
110336 |
static bool
|
|
|
110336 |
@@ -2878,7 +2869,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index)
|
|
|
110336 |
while (raft->commit_index < new_commit_index) {
|
|
|
110336 |
uint64_t index = ++raft->commit_index;
|
|
|
110336 |
const struct raft_entry *e = raft_get_entry(raft, index);
|
|
|
110336 |
- if (e->data) {
|
|
|
110336 |
+ if (raft_entry_has_data(e)) {
|
|
|
110336 |
struct raft_command *cmd
|
|
|
110336 |
= raft_find_command_by_eid(raft, &e->eid);
|
|
|
110336 |
if (cmd) {
|
|
|
110336 |
@@ -3059,7 +3050,9 @@ raft_handle_append_entries(struct raft *raft,
|
|
|
110336 |
for (; i < n_entries; i++) {
|
|
|
110336 |
const struct raft_entry *e = &entries[i];
|
|
|
110336 |
error = raft_write_entry(raft, e->term,
|
|
|
110336 |
- json_nullable_clone(e->data), &e->eid,
|
|
|
110336 |
+ json_nullable_clone(
|
|
|
110336 |
+ raft_entry_get_parsed_data(e)),
|
|
|
110336 |
+ &e->eid,
|
|
|
110336 |
json_nullable_clone(e->servers),
|
|
|
110336 |
e->election_timer);
|
|
|
110336 |
if (error) {
|
|
|
110336 |
@@ -3314,20 +3307,29 @@ bool
|
|
|
110336 |
raft_has_next_entry(const struct raft *raft_)
|
|
|
110336 |
{
|
|
|
110336 |
struct raft *raft = CONST_CAST(struct raft *, raft_);
|
|
|
110336 |
- struct uuid eid;
|
|
|
110336 |
- return raft_peek_next_entry(raft, &eid) != NULL;
|
|
|
110336 |
+ return raft_peek_next_entry(raft) != NULL;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
/* Returns the next log entry or snapshot from 'raft', or NULL if there are
|
|
|
110336 |
- * none left to read. Stores the entry ID of the log entry in '*eid'. Stores
|
|
|
110336 |
- * true in '*is_snapshot' if the returned data is a snapshot, false if it is a
|
|
|
110336 |
- * log entry. */
|
|
|
110336 |
-const struct json *
|
|
|
110336 |
-raft_next_entry(struct raft *raft, struct uuid *eid, bool *is_snapshot)
|
|
|
110336 |
+ * none left to read. Stores the entry ID of the log entry in '*eid'.
|
|
|
110336 |
+ *
|
|
|
110336 |
+ * The caller takes ownership of the result. */
|
|
|
110336 |
+struct json * OVS_WARN_UNUSED_RESULT
|
|
|
110336 |
+raft_next_entry(struct raft *raft, struct uuid *eid)
|
|
|
110336 |
{
|
|
|
110336 |
- const struct json *data = raft_get_next_entry(raft, eid);
|
|
|
110336 |
- *is_snapshot = data == raft->snap.data;
|
|
|
110336 |
- return data;
|
|
|
110336 |
+ const struct raft_entry *e = raft_peek_next_entry(raft);
|
|
|
110336 |
+
|
|
|
110336 |
+ if (!e) {
|
|
|
110336 |
+ return NULL;
|
|
|
110336 |
+ }
|
|
|
110336 |
+
|
|
|
110336 |
+ raft->last_applied++;
|
|
|
110336 |
+ *eid = e->eid;
|
|
|
110336 |
+
|
|
|
110336 |
+ /* DB will only read each entry once, so we don't need to store the fully
|
|
|
110336 |
+ * parsed json object any longer. The serialized version is sufficient
|
|
|
110336 |
+ * for sending to other cluster members or writing to the log. */
|
|
|
110336 |
+ return raft_entry_steal_parsed_data(CONST_CAST(struct raft_entry *, e));
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
/* Returns the log index of the last-read snapshot or log entry. */
|
|
|
110336 |
@@ -3420,6 +3422,7 @@ raft_send_install_snapshot_request(struct raft *raft,
|
|
|
110336 |
const struct raft_server *s,
|
|
|
110336 |
const char *comment)
|
|
|
110336 |
{
|
|
|
110336 |
+ const struct json *data = raft_entry_get_serialized_data(&raft->snap);
|
|
|
110336 |
union raft_rpc rpc = {
|
|
|
110336 |
.install_snapshot_request = {
|
|
|
110336 |
.common = {
|
|
|
110336 |
@@ -3432,7 +3435,7 @@ raft_send_install_snapshot_request(struct raft *raft,
|
|
|
110336 |
.last_term = raft->snap.term,
|
|
|
110336 |
.last_servers = raft->snap.servers,
|
|
|
110336 |
.last_eid = raft->snap.eid,
|
|
|
110336 |
- .data = raft->snap.data,
|
|
|
110336 |
+ .data = CONST_CAST(struct json *, data),
|
|
|
110336 |
.election_timer = raft->election_timer, /* use latest value */
|
|
|
110336 |
}
|
|
|
110336 |
};
|
|
|
110336 |
@@ -3980,6 +3983,10 @@ raft_write_snapshot(struct raft *raft, struct ovsdb_log *log,
|
|
|
110336 |
uint64_t new_log_start,
|
|
|
110336 |
const struct raft_entry *new_snapshot)
|
|
|
110336 |
{
|
|
|
110336 |
+ /* Ensure that new snapshot contains serialized data object, so it will
|
|
|
110336 |
+ * not be allocated while serializing the on-stack raft header object. */
|
|
|
110336 |
+ ovs_assert(raft_entry_get_serialized_data(new_snapshot));
|
|
|
110336 |
+
|
|
|
110336 |
struct raft_header h = {
|
|
|
110336 |
.sid = raft->sid,
|
|
|
110336 |
.cid = raft->cid,
|
|
|
110336 |
@@ -3998,12 +4005,13 @@ raft_write_snapshot(struct raft *raft, struct ovsdb_log *log,
|
|
|
110336 |
/* Write log records. */
|
|
|
110336 |
for (uint64_t index = new_log_start; index < raft->log_end; index++) {
|
|
|
110336 |
const struct raft_entry *e = &raft->entries[index - raft->log_start];
|
|
|
110336 |
+ const struct json *log_data = raft_entry_get_serialized_data(e);
|
|
|
110336 |
struct raft_record r = {
|
|
|
110336 |
.type = RAFT_REC_ENTRY,
|
|
|
110336 |
.term = e->term,
|
|
|
110336 |
.entry = {
|
|
|
110336 |
.index = index,
|
|
|
110336 |
- .data = e->data,
|
|
|
110336 |
+ .data = CONST_CAST(struct json *, log_data),
|
|
|
110336 |
.servers = e->servers,
|
|
|
110336 |
.election_timer = e->election_timer,
|
|
|
110336 |
.eid = e->eid,
|
|
|
110336 |
@@ -4093,19 +4101,21 @@ raft_handle_install_snapshot_request__(
|
|
|
110336 |
|
|
|
110336 |
/* Case 3: The new snapshot starts past the end of our current log, so
|
|
|
110336 |
* discard all of our current log. */
|
|
|
110336 |
- const struct raft_entry new_snapshot = {
|
|
|
110336 |
+ struct raft_entry new_snapshot = {
|
|
|
110336 |
.term = rq->last_term,
|
|
|
110336 |
- .data = rq->data,
|
|
|
110336 |
.eid = rq->last_eid,
|
|
|
110336 |
- .servers = rq->last_servers,
|
|
|
110336 |
+ .servers = json_clone(rq->last_servers),
|
|
|
110336 |
.election_timer = rq->election_timer,
|
|
|
110336 |
};
|
|
|
110336 |
+ raft_entry_set_parsed_data(&new_snapshot, rq->data);
|
|
|
110336 |
+
|
|
|
110336 |
struct ovsdb_error *error = raft_save_snapshot(raft, new_log_start,
|
|
|
110336 |
&new_snapshot);
|
|
|
110336 |
if (error) {
|
|
|
110336 |
char *error_s = ovsdb_error_to_string_free(error);
|
|
|
110336 |
VLOG_WARN("could not save snapshot: %s", error_s);
|
|
|
110336 |
free(error_s);
|
|
|
110336 |
+ raft_entry_uninit(&new_snapshot);
|
|
|
110336 |
return false;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
@@ -4120,7 +4130,7 @@ raft_handle_install_snapshot_request__(
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
raft_entry_uninit(&raft->snap);
|
|
|
110336 |
- raft_entry_clone(&raft->snap, &new_snapshot);
|
|
|
110336 |
+ raft->snap = new_snapshot;
|
|
|
110336 |
|
|
|
110336 |
raft_get_servers_from_log(raft, VLL_INFO);
|
|
|
110336 |
raft_get_election_timer_from_log(raft);
|
|
|
110336 |
@@ -4265,11 +4275,12 @@ raft_store_snapshot(struct raft *raft, const struct json *new_snapshot_data)
|
|
|
110336 |
uint64_t new_log_start = raft->last_applied + 1;
|
|
|
110336 |
struct raft_entry new_snapshot = {
|
|
|
110336 |
.term = raft_get_term(raft, new_log_start - 1),
|
|
|
110336 |
- .data = json_clone(new_snapshot_data),
|
|
|
110336 |
.eid = *raft_get_eid(raft, new_log_start - 1),
|
|
|
110336 |
.servers = json_clone(raft_servers_for_index(raft, new_log_start - 1)),
|
|
|
110336 |
.election_timer = raft->election_timer,
|
|
|
110336 |
};
|
|
|
110336 |
+ raft_entry_set_parsed_data(&new_snapshot, new_snapshot_data);
|
|
|
110336 |
+
|
|
|
110336 |
struct ovsdb_error *error = raft_save_snapshot(raft, new_log_start,
|
|
|
110336 |
&new_snapshot);
|
|
|
110336 |
if (error) {
|
|
|
110336 |
@@ -4286,6 +4297,9 @@ raft_store_snapshot(struct raft *raft, const struct json *new_snapshot_data)
|
|
|
110336 |
memmove(&raft->entries[0], &raft->entries[new_log_start - raft->log_start],
|
|
|
110336 |
(raft->log_end - new_log_start) * sizeof *raft->entries);
|
|
|
110336 |
raft->log_start = new_log_start;
|
|
|
110336 |
+ /* It's a snapshot of the current database state, ovsdb-server will not
|
|
|
110336 |
+ * read it back. Destroying the parsed json object to not waste memory. */
|
|
|
110336 |
+ json_destroy(raft_entry_steal_parsed_data(&raft->snap));
|
|
|
110336 |
return NULL;
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
diff --git a/ovsdb/raft.h b/ovsdb/raft.h
|
|
|
110336 |
index 3545c41c2c..599bc0ae86 100644
|
|
|
110336 |
--- a/ovsdb/raft.h
|
|
|
110336 |
+++ b/ovsdb/raft.h
|
|
|
110336 |
@@ -132,8 +132,8 @@ bool raft_left(const struct raft *);
|
|
|
110336 |
bool raft_failed(const struct raft *);
|
|
|
110336 |
|
|
|
110336 |
/* Reading snapshots and log entries. */
|
|
|
110336 |
-const struct json *raft_next_entry(struct raft *, struct uuid *eid,
|
|
|
110336 |
- bool *is_snapshot);
|
|
|
110336 |
+struct json *raft_next_entry(struct raft *, struct uuid *eid)
|
|
|
110336 |
+ OVS_WARN_UNUSED_RESULT;
|
|
|
110336 |
bool raft_has_next_entry(const struct raft *);
|
|
|
110336 |
|
|
|
110336 |
uint64_t raft_get_applied_index(const struct raft *);
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ovsdb/rbac.c b/ovsdb/rbac.c
|
|
Open vSwitch CI |
3f9b5c |
index 2986027c90..ff411675f0 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/ovsdb/rbac.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ovsdb/rbac.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -53,8 +53,8 @@ ovsdb_find_row_by_string_key(const struct ovsdb_table *table,
|
|
Open vSwitch CI |
3f9b5c |
HMAP_FOR_EACH (row, hmap_node, &table->rows) {
|
|
Open vSwitch CI |
3f9b5c |
const struct ovsdb_datum *datum = &row->fields[column->index];
|
|
Open vSwitch CI |
3f9b5c |
for (size_t i = 0; i < datum->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
- if (datum->keys[i].string[0] &&
|
|
Open vSwitch CI |
3f9b5c |
- !strcmp(key, datum->keys[i].string)) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (datum->keys[i].s->string[0] &&
|
|
Open vSwitch CI |
3f9b5c |
+ !strcmp(key, datum->keys[i].s->string)) {
|
|
Open vSwitch CI |
3f9b5c |
return row;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
@@ -113,7 +113,7 @@ ovsdb_rbac_authorized(const struct ovsdb_row *perms,
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < datum->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
- const char *name = datum->keys[i].string;
|
|
Open vSwitch CI |
3f9b5c |
+ const char *name = datum->keys[i].s->string;
|
|
Open vSwitch CI |
3f9b5c |
const char *value = NULL;
|
|
Open vSwitch CI |
3f9b5c |
bool is_map;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -271,7 +271,7 @@ rbac_column_modification_permitted(const struct ovsdb_column *column,
|
|
Open vSwitch CI |
3f9b5c |
size_t i;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < modifiable->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
- char *name = modifiable->keys[i].string;
|
|
Open vSwitch CI |
3f9b5c |
+ char *name = modifiable->keys[i].s->string;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (!strcmp(name, column->name)) {
|
|
Open vSwitch CI |
3f9b5c |
return true;
|
|
|
110336 |
diff --git a/ovsdb/storage.c b/ovsdb/storage.c
|
|
|
110336 |
index d727b1eacd..9e32efe582 100644
|
|
|
110336 |
--- a/ovsdb/storage.c
|
|
|
110336 |
+++ b/ovsdb/storage.c
|
|
|
110336 |
@@ -268,9 +268,7 @@ ovsdb_storage_read(struct ovsdb_storage *storage,
|
|
|
110336 |
struct json *schema_json = NULL;
|
|
|
110336 |
struct json *txn_json = NULL;
|
|
|
110336 |
if (storage->raft) {
|
|
|
110336 |
- bool is_snapshot;
|
|
|
110336 |
- json = json_nullable_clone(
|
|
|
110336 |
- raft_next_entry(storage->raft, txnid, &is_snapshot));
|
|
|
110336 |
+ json = raft_next_entry(storage->raft, txnid);
|
|
|
110336 |
if (!json) {
|
|
|
110336 |
return NULL;
|
|
|
110336 |
} else if (json->type != JSON_ARRAY || json->array.n != 2) {
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c
|
|
Open vSwitch CI |
3f9b5c |
index 8ffefcf7c9..dcccc61c05 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/ovsdb/transaction.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/ovsdb/transaction.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -266,9 +266,9 @@ ovsdb_txn_adjust_atom_refs(struct ovsdb_txn *txn, const struct ovsdb_row *r,
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
static struct ovsdb_error * OVS_WARN_UNUSED_RESULT
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_txn_adjust_row_refs(struct ovsdb_txn *txn, const struct ovsdb_row *r,
|
|
Open vSwitch CI |
3f9b5c |
- const struct ovsdb_column *column, int delta)
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_column *column,
|
|
Open vSwitch CI |
3f9b5c |
+ const struct ovsdb_datum *field, int delta)
|
|
Open vSwitch CI |
3f9b5c |
{
|
|
Open vSwitch CI |
3f9b5c |
- const struct ovsdb_datum *field = &r->fields[column->index];
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_error *error;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
error = ovsdb_txn_adjust_atom_refs(txn, r, column, &column->type.key,
|
|
Open vSwitch CI |
3f9b5c |
@@ -291,14 +291,39 @@ update_row_ref_count(struct ovsdb_txn *txn, struct ovsdb_txn_row *r)
|
|
Open vSwitch CI |
3f9b5c |
struct ovsdb_error *error;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if (bitmap_is_set(r->changed, column->index)) {
|
|
Open vSwitch CI |
3f9b5c |
- if (r->old) {
|
|
Open vSwitch CI |
3f9b5c |
- error = ovsdb_txn_adjust_row_refs(txn, r->old, column, -1);
|
|
Open vSwitch CI |
3f9b5c |
+ if (r->old && !r->new) {
|
|
Open vSwitch CI |
3f9b5c |
+ error = ovsdb_txn_adjust_row_refs(
|
|
Open vSwitch CI |
3f9b5c |
+ txn, r->old, column,
|
|
Open vSwitch CI |
3f9b5c |
+ &r->old->fields[column->index], -1);
|
|
Open vSwitch CI |
3f9b5c |
if (error) {
|
|
Open vSwitch CI |
3f9b5c |
return OVSDB_WRAP_BUG("error decreasing refcount", error);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
- }
|
|
Open vSwitch CI |
3f9b5c |
- if (r->new) {
|
|
Open vSwitch CI |
3f9b5c |
- error = ovsdb_txn_adjust_row_refs(txn, r->new, column, 1);
|
|
Open vSwitch CI |
3f9b5c |
+ } else if (!r->old && r->new) {
|
|
Open vSwitch CI |
3f9b5c |
+ error = ovsdb_txn_adjust_row_refs(
|
|
Open vSwitch CI |
3f9b5c |
+ txn, r->new, column,
|
|
Open vSwitch CI |
3f9b5c |
+ &r->new->fields[column->index], 1);
|
|
Open vSwitch CI |
3f9b5c |
+ if (error) {
|
|
Open vSwitch CI |
3f9b5c |
+ return error;
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+ } else if (r->old && r->new) {
|
|
Open vSwitch CI |
3f9b5c |
+ struct ovsdb_datum added, removed;
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_added_removed(&added, &removed,
|
|
Open vSwitch CI |
3f9b5c |
+ &r->old->fields[column->index],
|
|
Open vSwitch CI |
3f9b5c |
+ &r->new->fields[column->index],
|
|
Open vSwitch CI |
3f9b5c |
+ &column->type);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ error = ovsdb_txn_adjust_row_refs(
|
|
Open vSwitch CI |
3f9b5c |
+ txn, r->old, column, &removed, -1);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&removed, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (error) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&added, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
+ return OVSDB_WRAP_BUG("error decreasing refcount", error);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ error = ovsdb_txn_adjust_row_refs(
|
|
Open vSwitch CI |
3f9b5c |
+ txn, r->new, column, &added, 1);
|
|
Open vSwitch CI |
3f9b5c |
+ ovsdb_datum_destroy(&added, &column->type);
|
|
Open vSwitch CI |
3f9b5c |
if (error) {
|
|
Open vSwitch CI |
3f9b5c |
return error;
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/python/ovs/db/data.py b/python/ovs/db/data.py
|
|
Open vSwitch CI |
3f9b5c |
index 2a2102d6be..99bf80ed62 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/python/ovs/db/data.py
|
|
Open vSwitch CI |
3f9b5c |
+++ b/python/ovs/db/data.py
|
|
Open vSwitch CI |
3f9b5c |
@@ -204,7 +204,7 @@ class Atom(object):
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
return '.boolean = false'
|
|
Open vSwitch CI |
3f9b5c |
elif self.type == ovs.db.types.StringType:
|
|
Open vSwitch CI |
3f9b5c |
- return '.string = "%s"' % escapeCString(self.value)
|
|
Open vSwitch CI |
3f9b5c |
+ return '.s = %s' % escapeCString(self.value)
|
|
Open vSwitch CI |
3f9b5c |
elif self.type == ovs.db.types.UuidType:
|
|
Open vSwitch CI |
3f9b5c |
return '.uuid = %s' % ovs.ovsuuid.to_c_assignment(self.value)
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -563,16 +563,41 @@ class Datum(object):
|
|
Open vSwitch CI |
3f9b5c |
if n == 0:
|
|
Open vSwitch CI |
3f9b5c |
return ["static struct ovsdb_datum %s = { .n = 0 };"]
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
- s = ["static union ovsdb_atom %s_keys[%d] = {" % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
- for key in sorted(self.values):
|
|
Open vSwitch CI |
3f9b5c |
- s += [" { %s }," % key.cInitAtom(key)]
|
|
Open vSwitch CI |
3f9b5c |
- s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
+ s = []
|
|
Open vSwitch CI |
3f9b5c |
+ if self.type.key.type == ovs.db.types.StringType:
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["static struct ovsdb_atom_string %s_key_strings[%d] = {"
|
|
Open vSwitch CI |
3f9b5c |
+ % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
+ for key in sorted(self.values):
|
|
Open vSwitch CI |
3f9b5c |
+ s += [' { .string = "%s", .n_refs = 2 },'
|
|
Open vSwitch CI |
3f9b5c |
+ % escapeCString(key.value)]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["static union ovsdb_atom %s_keys[%d] = {" % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
+ for i in range(n):
|
|
Open vSwitch CI |
3f9b5c |
+ s += [" { .s = &%s_key_strings[%d] }," % (name, i)]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
+ else:
|
|
Open vSwitch CI |
3f9b5c |
+ s = ["static union ovsdb_atom %s_keys[%d] = {" % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
+ for key in sorted(self.values):
|
|
Open vSwitch CI |
3f9b5c |
+ s += [" { %s }," % key.cInitAtom(key)]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
if self.type.value:
|
|
Open vSwitch CI |
3f9b5c |
- s = ["static union ovsdb_atom %s_values[%d] = {" % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
- for k, v in sorted(self.values.items()):
|
|
Open vSwitch CI |
3f9b5c |
- s += [" { %s }," % v.cInitAtom(v)]
|
|
Open vSwitch CI |
3f9b5c |
- s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
+ if self.type.value.type == ovs.db.types.StringType:
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["static struct ovsdb_atom_string %s_val_strings[%d] = {"
|
|
Open vSwitch CI |
3f9b5c |
+ % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
+ for k, v in sorted(self.values):
|
|
Open vSwitch CI |
3f9b5c |
+ s += [' { .string = "%s", .n_refs = 2 },'
|
|
Open vSwitch CI |
3f9b5c |
+ % escapeCString(v.value)]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["static union ovsdb_atom %s_values[%d] = {" % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
+ for i in range(n):
|
|
Open vSwitch CI |
3f9b5c |
+ s += [" { .s = &%s_val_strings[%d] }," % (name, i)]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
+ else:
|
|
Open vSwitch CI |
3f9b5c |
+ s = ["static union ovsdb_atom %s_values[%d] = {" % (name, n)]
|
|
Open vSwitch CI |
3f9b5c |
+ for k, v in sorted(self.values.items()):
|
|
Open vSwitch CI |
3f9b5c |
+ s += [" { %s }," % v.cInitAtom(v)]
|
|
Open vSwitch CI |
3f9b5c |
+ s += ["};"]
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
s += ["static struct ovsdb_datum %s = {" % name]
|
|
Open vSwitch CI |
3f9b5c |
s += [" .n = %d," % n]
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
|
|
Open vSwitch CI |
3f9b5c |
index ecae5e1432..87ee06cdef 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/python/ovs/db/idl.py
|
|
Open vSwitch CI |
3f9b5c |
+++ b/python/ovs/db/idl.py
|
|
Open vSwitch CI |
3f9b5c |
@@ -1505,6 +1505,11 @@ class Transaction(object):
|
|
Open vSwitch CI |
3f9b5c |
if self != self.idl.txn:
|
|
Open vSwitch CI |
3f9b5c |
return self._status
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+ if self.idl.state != Idl.IDL_S_MONITORING:
|
|
Open vSwitch CI |
3f9b5c |
+ self._status = Transaction.TRY_AGAIN
|
|
Open vSwitch CI |
3f9b5c |
+ self.__disassemble()
|
|
Open vSwitch CI |
3f9b5c |
+ return self._status
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
# If we need a lock but don't have it, give up quickly.
|
|
Open vSwitch CI |
3f9b5c |
if self.idl.lock_name and not self.idl.has_lock:
|
|
Open vSwitch CI |
3f9b5c |
self._status = Transaction.NOT_LOCKED
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/python/ovs/db/types.py b/python/ovs/db/types.py
|
|
Open vSwitch CI |
3f9b5c |
index 626ae8fc44..3318a3b6f8 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/python/ovs/db/types.py
|
|
Open vSwitch CI |
3f9b5c |
+++ b/python/ovs/db/types.py
|
|
Open vSwitch CI |
3f9b5c |
@@ -48,6 +48,16 @@ class AtomicType(object):
|
|
Open vSwitch CI |
3f9b5c |
def to_string(self):
|
|
Open vSwitch CI |
3f9b5c |
return self.name
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+ def to_rvalue_string(self):
|
|
Open vSwitch CI |
3f9b5c |
+ if self == StringType:
|
|
Open vSwitch CI |
3f9b5c |
+ return 's->' + self.name
|
|
Open vSwitch CI |
3f9b5c |
+ return self.name
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ def to_lvalue_string(self):
|
|
Open vSwitch CI |
3f9b5c |
+ if self == StringType:
|
|
Open vSwitch CI |
3f9b5c |
+ return 's'
|
|
Open vSwitch CI |
3f9b5c |
+ return self.name
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
def to_json(self):
|
|
Open vSwitch CI |
3f9b5c |
return self.name
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
@@ -373,18 +383,7 @@ class BaseType(object):
|
|
Open vSwitch CI |
3f9b5c |
return "%(dst)s = *%(src)s;" % args
|
|
Open vSwitch CI |
3f9b5c |
return ("%(dst)s = %(src)s->header_.uuid;") % args
|
|
Open vSwitch CI |
3f9b5c |
elif self.type == StringType:
|
|
Open vSwitch CI |
3f9b5c |
- return "%(dst)s = xstrdup(%(src)s);" % args
|
|
Open vSwitch CI |
3f9b5c |
- else:
|
|
Open vSwitch CI |
3f9b5c |
- return "%(dst)s = %(src)s;" % args
|
|
Open vSwitch CI |
3f9b5c |
-
|
|
Open vSwitch CI |
3f9b5c |
- def assign_c_value_casting_away_const(self, dst, src, refTable=True):
|
|
Open vSwitch CI |
3f9b5c |
- args = {'dst': dst, 'src': src}
|
|
Open vSwitch CI |
3f9b5c |
- if self.ref_table_name:
|
|
Open vSwitch CI |
3f9b5c |
- if not refTable:
|
|
Open vSwitch CI |
3f9b5c |
- return "%(dst)s = *%(src)s;" % args
|
|
Open vSwitch CI |
3f9b5c |
- return ("%(dst)s = %(src)s->header_.uuid;") % args
|
|
Open vSwitch CI |
3f9b5c |
- elif self.type == StringType:
|
|
Open vSwitch CI |
3f9b5c |
- return "%(dst)s = CONST_CAST(char *, %(src)s);" % args
|
|
Open vSwitch CI |
3f9b5c |
+ return "%(dst)s = ovsdb_atom_string_create(%(src)s);" % args
|
|
Open vSwitch CI |
3f9b5c |
else:
|
|
Open vSwitch CI |
3f9b5c |
return "%(dst)s = %(src)s;" % args
|
|
Open vSwitch CI |
3f9b5c |
|
|
|
110336 |
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
|
|
|
110336 |
index 956a69e1fa..1dad6f62c6 100644
|
|
|
110336 |
--- a/tests/ofproto-dpif.at
|
|
|
110336 |
+++ b/tests/ofproto-dpif.at
|
|
|
110336 |
@@ -9695,6 +9695,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2):
|
|
|
110336 |
OVS_VSWITCHD_STOP
|
|
|
110336 |
AT_CLEANUP
|
|
|
110336 |
|
|
|
110336 |
+AT_SETUP([ofproto-dpif packet-out table meter drop])
|
|
|
110336 |
+OVS_VSWITCHD_START
|
|
|
110336 |
+add_of_ports br0 1 2
|
|
|
110336 |
+
|
|
|
110336 |
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=1 pktps bands=type=drop rate=1'])
|
|
|
110336 |
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 'in_port=1 action=meter:1,output:2'])
|
|
|
110336 |
+
|
|
|
110336 |
+ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000400080000 actions=resubmit(,0)"
|
|
|
110336 |
+ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000400080000 actions=resubmit(,0)"
|
|
|
110336 |
+
|
|
|
110336 |
+# Check that vswitchd hasn't crashed by dumping the meter added above
|
|
|
110336 |
+AT_CHECK([ovs-ofctl -O OpenFlow13 dump-meters br0 | ofctl_strip], [0], [dnl
|
|
|
110336 |
+OFPST_METER_CONFIG reply (OF1.3):
|
|
|
110336 |
+meter=1 pktps bands=
|
|
|
110336 |
+type=drop rate=1
|
|
|
110336 |
+])
|
|
|
110336 |
+
|
|
|
110336 |
+OVS_VSWITCHD_STOP
|
|
|
110336 |
+AT_CLEANUP
|
|
|
110336 |
+
|
|
|
110336 |
AT_SETUP([ofproto-dpif - ICMPv6])
|
|
|
110336 |
OVS_VSWITCHD_START
|
|
|
110336 |
add_of_ports br0 1
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/tests/ovsdb-data.at b/tests/ovsdb-data.at
|
|
Open vSwitch CI |
3f9b5c |
index 8cd2a26cb3..25c6acdac6 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/tests/ovsdb-data.at
|
|
Open vSwitch CI |
3f9b5c |
+++ b/tests/ovsdb-data.at
|
|
Open vSwitch CI |
3f9b5c |
@@ -846,18 +846,21 @@ OVSDB_CHECK_POSITIVE([generate and apply diff -- integer],
|
|
Open vSwitch CI |
3f9b5c |
[[diff-data '["integer"]' '[0]' '[2]']],
|
|
Open vSwitch CI |
3f9b5c |
[[diff: 2
|
|
Open vSwitch CI |
3f9b5c |
apply diff: 2
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: 2
|
|
Open vSwitch CI |
3f9b5c |
OK]])
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
OVSDB_CHECK_POSITIVE([generate and apply diff -- boolean],
|
|
Open vSwitch CI |
3f9b5c |
[[diff-data '["boolean"]' '[true]' '[false]']],
|
|
Open vSwitch CI |
3f9b5c |
[[diff: false
|
|
Open vSwitch CI |
3f9b5c |
apply diff: false
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: false
|
|
Open vSwitch CI |
3f9b5c |
OK]])
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
OVSDB_CHECK_POSITIVE([generate and apply diff -- string],
|
|
Open vSwitch CI |
3f9b5c |
[[diff-data '["string"]' '["AAA"]' '["BBB"]']],
|
|
Open vSwitch CI |
3f9b5c |
[[diff: "BBB"
|
|
Open vSwitch CI |
3f9b5c |
apply diff: "BBB"
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: "BBB"
|
|
Open vSwitch CI |
3f9b5c |
OK]])
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
dnl Test set modifications.
|
|
Open vSwitch CI |
3f9b5c |
@@ -870,15 +873,19 @@ OVSDB_CHECK_POSITIVE([generate and apply diff -- set],
|
|
Open vSwitch CI |
3f9b5c |
]],
|
|
Open vSwitch CI |
3f9b5c |
[[diff: ["set",[0,2]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["set",[1,2]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["set",[1,2]]
|
|
Open vSwitch CI |
3f9b5c |
OK
|
|
Open vSwitch CI |
3f9b5c |
diff: 0
|
|
Open vSwitch CI |
3f9b5c |
apply diff: 1
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: 1
|
|
Open vSwitch CI |
3f9b5c |
OK
|
|
Open vSwitch CI |
3f9b5c |
diff: ["set",[0,1]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["set",[0,1]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["set",[0,1]]
|
|
Open vSwitch CI |
3f9b5c |
OK
|
|
Open vSwitch CI |
3f9b5c |
diff: ["set",[0,1]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["set",[]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["set",[]]
|
|
Open vSwitch CI |
3f9b5c |
OK]])
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
dnl Test set modifications causes data to violate set size constrain.
|
|
Open vSwitch CI |
3f9b5c |
@@ -898,18 +905,23 @@ OVSDB_CHECK_POSITIVE([generate and apply diff -- map],
|
|
Open vSwitch CI |
3f9b5c |
]],
|
|
Open vSwitch CI |
3f9b5c |
[[diff: ["map",[["2 gills","1 chopin"],["2 pints","1 quart"]]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["map",[["2 pints","1 quart"]]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["map",[["2 pints","1 quart"]]]
|
|
Open vSwitch CI |
3f9b5c |
OK
|
|
Open vSwitch CI |
3f9b5c |
diff: ["map",[]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["map",[["2 gills","1 chopin"]]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["map",[["2 gills","1 chopin"]]]
|
|
Open vSwitch CI |
3f9b5c |
OK
|
|
Open vSwitch CI |
3f9b5c |
diff: ["map",[["2 gills","1 chopin"]]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["map",[]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["map",[]]
|
|
Open vSwitch CI |
3f9b5c |
OK
|
|
Open vSwitch CI |
3f9b5c |
diff: ["map",[["2 pints","1 quart"]]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["map",[["2 pints","1 quart"]]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["map",[["2 pints","1 quart"]]]
|
|
Open vSwitch CI |
3f9b5c |
OK
|
|
Open vSwitch CI |
3f9b5c |
diff: ["map",[["2 gills","1 gallon"]]]
|
|
Open vSwitch CI |
3f9b5c |
apply diff: ["map",[["2 gills","1 gallon"]]]
|
|
Open vSwitch CI |
3f9b5c |
+apply diff in place: ["map",[["2 gills","1 gallon"]]]
|
|
Open vSwitch CI |
3f9b5c |
OK]])
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
OVSDB_CHECK_NEGATIVE([generate and apply diff with map -- size error],
|
|
|
110336 |
diff --git a/tests/system-traffic.at b/tests/system-traffic.at
|
|
Open vSwitch CI |
3f9b5c |
index f400cfabc9..092de308be 100644
|
|
|
110336 |
--- a/tests/system-traffic.at
|
|
|
110336 |
+++ b/tests/system-traffic.at
|
|
Open vSwitch CI |
3f9b5c |
@@ -1981,6 +1981,111 @@ tcp,orig=(src=10.1.1.3,dst=10.1.1.4,sport=<cleared>,dport=<cleared>),reply=(src=
|
|
Open vSwitch CI |
3f9b5c |
OVS_TRAFFIC_VSWITCHD_STOP
|
|
Open vSwitch CI |
3f9b5c |
AT_CLEANUP
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+AT_SETUP([conntrack - zones from other field])
|
|
Open vSwitch CI |
3f9b5c |
+CHECK_CONNTRACK()
|
|
Open vSwitch CI |
3f9b5c |
+OVS_TRAFFIC_VSWITCHD_START()
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ADD_NAMESPACES(at_ns0, at_ns1)
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
|
|
Open vSwitch CI |
3f9b5c |
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0.
|
|
Open vSwitch CI |
3f9b5c |
+AT_DATA([flows.txt], [dnl
|
|
Open vSwitch CI |
3f9b5c |
+priority=1,action=drop
|
|
Open vSwitch CI |
3f9b5c |
+priority=10,arp,action=normal
|
|
Open vSwitch CI |
3f9b5c |
+priority=10,icmp,action=normal
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=1,tcp,ct_state=-trk,action=ct(zone=5,table=0)
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=1,tcp,ct_state=+trk,action=ct(commit,zone=NXM_NX_CT_ZONE[]),2
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0,zone=5)
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=2,ct_state=+trk,ct_zone=5,tcp,action=1
|
|
Open vSwitch CI |
3f9b5c |
+])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+OVS_START_L7([at_ns1], [http])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+dnl HTTP requests from p0->p1 should work fine.
|
|
Open vSwitch CI |
3f9b5c |
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
|
|
Open vSwitch CI |
3f9b5c |
+tcp,dnl
|
|
Open vSwitch CI |
3f9b5c |
+orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),dnl
|
|
Open vSwitch CI |
3f9b5c |
+reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),dnl
|
|
Open vSwitch CI |
3f9b5c |
+zone=5,protoinfo=(state=<cleared>)
|
|
Open vSwitch CI |
3f9b5c |
+])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+dnl This is to test when the zoneid is set by a field variable like
|
|
Open vSwitch CI |
3f9b5c |
+dnl NXM_NX_CT_ZONE, the OVS xlate should generate a megaflow with a form of
|
|
Open vSwitch CI |
3f9b5c |
+dnl "ct_zone(5), ... actions: ct(commit, zone=5)". The match "ct_zone(5)"
|
|
Open vSwitch CI |
3f9b5c |
+dnl is needed as if we changes the zoneid into 15 in the following, the old
|
|
Open vSwitch CI |
3f9b5c |
+dnl "ct_zone(5), ... actions: ct(commit, zone=5)" megaflow will not get hit,
|
|
Open vSwitch CI |
3f9b5c |
+dnl and OVS will generate a new megaflow with the match "ct_zone(0xf)".
|
|
Open vSwitch CI |
3f9b5c |
+dnl This will make sure that the new packets are committing to zoneid 15
|
|
Open vSwitch CI |
3f9b5c |
+dnl rather than old 5.
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
|
|
Open vSwitch CI |
3f9b5c |
+ | grep "+trk" | grep -q "ct_zone(0x5)" ], [0], [])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-ofctl mod-flows br0 dnl
|
|
Open vSwitch CI |
3f9b5c |
+ 'priority=100,ct_state=-trk,tcp,in_port="ovs-p0" actions=ct(table=0,zone=15)'])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
|
|
Open vSwitch CI |
3f9b5c |
+ | grep "+trk" | grep -q "ct_zone(0xf)" ], [0], [])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+OVS_TRAFFIC_VSWITCHD_STOP
|
|
Open vSwitch CI |
3f9b5c |
+AT_CLEANUP
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_SETUP([conntrack - zones from other field, more tests])
|
|
Open vSwitch CI |
3f9b5c |
+CHECK_CONNTRACK()
|
|
Open vSwitch CI |
3f9b5c |
+OVS_TRAFFIC_VSWITCHD_START()
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ADD_NAMESPACES(at_ns0, at_ns1)
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
|
|
Open vSwitch CI |
3f9b5c |
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0.
|
|
Open vSwitch CI |
3f9b5c |
+AT_DATA([flows.txt], [dnl
|
|
Open vSwitch CI |
3f9b5c |
+priority=1,action=drop
|
|
Open vSwitch CI |
3f9b5c |
+priority=10,arp,action=normal
|
|
Open vSwitch CI |
3f9b5c |
+priority=10,icmp,action=normal
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=1,tcp,ct_state=-trk,action=ct(zone=5,table=0,commit,exec(load:0xffff0005->NXM_NX_CT_LABEL[[0..31]]))
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=1,tcp,ct_state=+trk,action=ct(commit,zone=NXM_NX_CT_LABEL[[0..15]]),2
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0,zone=5)
|
|
Open vSwitch CI |
3f9b5c |
+priority=100,in_port=2,ct_state=+trk,ct_zone=5,tcp,action=1
|
|
Open vSwitch CI |
3f9b5c |
+])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+OVS_START_L7([at_ns1], [http])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+dnl HTTP requests from p0->p1 should work fine.
|
|
Open vSwitch CI |
3f9b5c |
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
|
|
Open vSwitch CI |
3f9b5c |
+tcp,dnl
|
|
Open vSwitch CI |
3f9b5c |
+orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),dnl
|
|
Open vSwitch CI |
3f9b5c |
+reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),dnl
|
|
Open vSwitch CI |
3f9b5c |
+zone=5,labels=0xffff0005,protoinfo=(state=<cleared>)
|
|
Open vSwitch CI |
3f9b5c |
+])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
|
|
Open vSwitch CI |
3f9b5c |
+ | grep "+trk" | sed 's/0xffff0005\/0xffff/0x5\/0xffff/' dnl
|
|
Open vSwitch CI |
3f9b5c |
+ | grep -q "ct_label(0x5/0xffff)" ], [0], [])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-ofctl mod-flows br0 'priority=100,ct_state=-trk,tcp,in_port="ovs-p0" actions=ct(table=0,zone=15,commit,exec(load:0xffff000f->NXM_NX_CT_LABEL[[0..31]]))'])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
|
|
Open vSwitch CI |
3f9b5c |
+ | grep "+trk" | sed 's/0xffff000f\/0xffff/0xf\/0xffff/' dnl
|
|
Open vSwitch CI |
3f9b5c |
+ | grep -q "ct_label(0xf/0xffff)" ], [0], [])
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+OVS_TRAFFIC_VSWITCHD_STOP
|
|
Open vSwitch CI |
3f9b5c |
+AT_CLEANUP
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
AT_SETUP([conntrack - multiple bridges])
|
|
Open vSwitch CI |
3f9b5c |
CHECK_CONNTRACK()
|
|
Open vSwitch CI |
3f9b5c |
OVS_TRAFFIC_VSWITCHD_START(
|
|
Open vSwitch CI |
3f9b5c |
@@ -3305,6 +3410,46 @@ NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING
|
|
|
110336 |
OVS_TRAFFIC_VSWITCHD_STOP
|
|
|
110336 |
AT_CLEANUP
|
|
|
110336 |
|
|
|
110336 |
+AT_SETUP([conntrack - IPv4 Fragmentation + NAT])
|
|
|
110336 |
+AT_SKIP_IF([test $HAVE_TCPDUMP = no])
|
|
|
110336 |
+CHECK_CONNTRACK()
|
|
|
110336 |
+
|
|
|
110336 |
+OVS_TRAFFIC_VSWITCHD_START(
|
|
|
110336 |
+ [set-fail-mode br0 secure -- ])
|
|
|
110336 |
+
|
|
|
110336 |
+ADD_NAMESPACES(at_ns0, at_ns1)
|
|
|
110336 |
+
|
|
|
110336 |
+ADD_VETH(p0, at_ns0, br0, "10.2.1.1/24")
|
|
|
110336 |
+ADD_VETH(p1, at_ns1, br0, "10.2.1.2/24")
|
|
|
110336 |
+
|
|
|
110336 |
+dnl Create a dummy route for NAT
|
|
|
110336 |
+NS_CHECK_EXEC([at_ns1], [ip addr add 10.1.1.2/32 dev lo])
|
|
|
110336 |
+NS_CHECK_EXEC([at_ns0], [ip route add 10.1.1.0/24 via 10.2.1.2])
|
|
|
110336 |
+NS_CHECK_EXEC([at_ns1], [ip route add 10.1.1.0/24 via 10.2.1.1])
|
|
|
110336 |
+
|
|
|
110336 |
+dnl Solely for debugging when things go wrong
|
|
|
110336 |
+NS_EXEC([at_ns0], [tcpdump -l -n -xx -U -i p0 -w p0.pcap >tcpdump.out 2>/dev/null &])
|
|
|
110336 |
+NS_EXEC([at_ns1], [tcpdump -l -n -xx -U -i p1 -w p1.pcap >tcpdump.out 2>/dev/null &])
|
|
|
110336 |
+
|
|
|
110336 |
+AT_DATA([flows.txt], [dnl
|
|
|
110336 |
+table=0,arp,actions=normal
|
|
|
110336 |
+table=0,ct_state=-trk,ip,in_port=ovs-p0, actions=ct(table=1, nat)
|
|
|
110336 |
+table=0,ct_state=-trk,ip,in_port=ovs-p1, actions=ct(table=1, nat)
|
|
|
110336 |
+table=1,ct_state=+trk+new,ip,in_port=ovs-p0, actions=ct(commit, nat(src=10.1.1.1)),ovs-p1
|
|
|
110336 |
+table=1,ct_state=+trk+est,ip,in_port=ovs-p0, actions=ovs-p1
|
|
|
110336 |
+table=1,ct_state=+trk+est,ip,in_port=ovs-p1, actions=ovs-p0
|
|
|
110336 |
+])
|
|
|
110336 |
+
|
|
|
110336 |
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
|
|
|
110336 |
+
|
|
|
110336 |
+dnl Check connectivity
|
|
|
110336 |
+NS_CHECK_EXEC([at_ns0], [ping -c 1 10.1.1.2 -M dont -s 4500 | FORMAT_PING], [0], [dnl
|
|
|
110336 |
+1 packets transmitted, 1 received, 0% packet loss, time 0ms
|
|
|
110336 |
+])
|
|
|
110336 |
+
|
|
|
110336 |
+OVS_TRAFFIC_VSWITCHD_STOP
|
|
|
110336 |
+AT_CLEANUP
|
|
|
110336 |
+
|
|
|
110336 |
AT_SETUP([conntrack - resubmit to ct multiple times])
|
|
|
110336 |
CHECK_CONNTRACK()
|
|
|
110336 |
|
|
|
110336 |
diff --git a/tests/test-json.c b/tests/test-json.c
|
|
|
110336 |
index a7ee595e0b..072a537252 100644
|
|
|
110336 |
--- a/tests/test-json.c
|
|
|
110336 |
+++ b/tests/test-json.c
|
|
|
110336 |
@@ -22,6 +22,8 @@
|
|
|
110336 |
#include <getopt.h>
|
|
|
110336 |
#include <stdio.h>
|
|
|
110336 |
#include "ovstest.h"
|
|
|
110336 |
+#include "random.h"
|
|
|
110336 |
+#include "timeval.h"
|
|
|
110336 |
#include "util.h"
|
|
|
110336 |
|
|
|
110336 |
/* --pretty: If set, the JSON output is pretty-printed, instead of printed as
|
|
|
110336 |
@@ -157,3 +159,69 @@ test_json_main(int argc, char *argv[])
|
|
|
110336 |
}
|
|
|
110336 |
|
|
|
110336 |
OVSTEST_REGISTER("test-json", test_json_main);
|
|
|
110336 |
+
|
|
|
110336 |
+static void
|
|
|
110336 |
+json_string_benchmark_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
|
110336 |
+{
|
|
|
110336 |
+ struct {
|
|
|
110336 |
+ int n;
|
|
|
110336 |
+ int quote_probablility;
|
|
|
110336 |
+ int special_probability;
|
|
|
110336 |
+ int iter;
|
|
|
110336 |
+ } configs[] = {
|
|
|
110336 |
+ { 100000, 0, 0, 1000, },
|
|
|
110336 |
+ { 100000, 2, 1, 1000, },
|
|
|
110336 |
+ { 100000, 10, 1, 1000, },
|
|
|
110336 |
+ { 10000000, 0, 0, 100, },
|
|
|
110336 |
+ { 10000000, 2, 1, 100, },
|
|
|
110336 |
+ { 10000000, 10, 1, 100, },
|
|
|
110336 |
+ { 100000000, 0, 0, 10. },
|
|
|
110336 |
+ { 100000000, 2, 1, 10, },
|
|
|
110336 |
+ { 100000000, 10, 1, 10, },
|
|
|
110336 |
+ };
|
|
|
110336 |
+
|
|
|
110336 |
+ printf(" SIZE Q S TIME\n");
|
|
|
110336 |
+ printf("--------------------------------------\n");
|
|
|
110336 |
+
|
|
|
110336 |
+ for (int i = 0; i < ARRAY_SIZE(configs); i++) {
|
|
|
110336 |
+ int iter = configs[i].iter;
|
|
|
110336 |
+ int n = configs[i].n;
|
|
|
110336 |
+ char *str = xzalloc(n);
|
|
|
110336 |
+
|
|
|
110336 |
+ for (int j = 0; j < n - 1; j++) {
|
|
|
110336 |
+ int r = random_range(100);
|
|
|
110336 |
+
|
|
|
110336 |
+ if (r < configs[i].special_probability) {
|
|
|
110336 |
+ str[j] = random_range(' ' - 1) + 1;
|
|
|
110336 |
+ } else if (r < (configs[i].special_probability
|
|
|
110336 |
+ + configs[i].quote_probablility)) {
|
|
|
110336 |
+ str[j] = '"';
|
|
|
110336 |
+ } else {
|
|
|
110336 |
+ str[j] = random_range(256 - ' ') + ' ';
|
|
|
110336 |
+ }
|
|
|
110336 |
+ }
|
|
|
110336 |
+
|
|
|
110336 |
+ printf("%-11d %-2d %-2d: ", n, configs[i].quote_probablility,
|
|
|
110336 |
+ configs[i].special_probability);
|
|
|
110336 |
+ fflush(stdout);
|
|
|
110336 |
+
|
|
|
110336 |
+ struct json *json = json_string_create_nocopy(str);
|
|
|
110336 |
+ uint64_t start = time_msec();
|
|
|
110336 |
+
|
|
|
110336 |
+ char **res = xzalloc(iter * sizeof *res);
|
|
|
110336 |
+ for (int j = 0; j < iter; j++) {
|
|
|
110336 |
+ res[j] = json_to_string(json, 0);
|
|
|
110336 |
+ }
|
|
|
110336 |
+
|
|
|
110336 |
+ printf("%16.3lf ms\n", (double) (time_msec() - start) / iter);
|
|
|
110336 |
+ json_destroy(json);
|
|
|
110336 |
+ for (int j = 0; j < iter; j++) {
|
|
|
110336 |
+ free(res[j]);
|
|
|
110336 |
+ }
|
|
|
110336 |
+ free(res);
|
|
|
110336 |
+ }
|
|
|
110336 |
+
|
|
|
110336 |
+ exit(0);
|
|
|
110336 |
+}
|
|
|
110336 |
+
|
|
|
110336 |
+OVSTEST_REGISTER("json-string-benchmark", json_string_benchmark_main);
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
|
|
Open vSwitch CI |
3f9b5c |
index daa55dab7b..637271619f 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/tests/test-ovsdb.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/tests/test-ovsdb.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -512,6 +512,18 @@ do_diff_data(struct ovs_cmdl_context *ctx)
|
|
Open vSwitch CI |
3f9b5c |
ovs_fatal(0, "failed to apply diff");
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+ /* Apply diff to 'old' in place. */
|
|
Open vSwitch CI |
3f9b5c |
+ error = ovsdb_datum_apply_diff_in_place(&old, &diff, &type);
|
|
Open vSwitch CI |
3f9b5c |
+ if (error) {
|
|
Open vSwitch CI |
3f9b5c |
+ char *string = ovsdb_error_to_string_free(error);
|
|
Open vSwitch CI |
3f9b5c |
+ ovs_fatal(0, "%s", string);
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
+ /* Test to make sure 'old' equals 'new' now. */
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_equals(&new, &old, &type)) {
|
|
Open vSwitch CI |
3f9b5c |
+ ovs_fatal(0, "failed to apply diff in place");
|
|
Open vSwitch CI |
3f9b5c |
+ }
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
/* Print diff */
|
|
Open vSwitch CI |
3f9b5c |
json = ovsdb_datum_to_json(&diff, &type);
|
|
Open vSwitch CI |
3f9b5c |
printf ("diff: ");
|
|
Open vSwitch CI |
3f9b5c |
@@ -522,6 +534,11 @@ do_diff_data(struct ovs_cmdl_context *ctx)
|
|
Open vSwitch CI |
3f9b5c |
printf ("apply diff: ");
|
|
Open vSwitch CI |
3f9b5c |
print_and_free_json(json);
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
+ /* Print updated 'old' */
|
|
Open vSwitch CI |
3f9b5c |
+ json = ovsdb_datum_to_json(&old, &type);
|
|
Open vSwitch CI |
3f9b5c |
+ printf ("apply diff in place: ");
|
|
Open vSwitch CI |
3f9b5c |
+ print_and_free_json(json);
|
|
Open vSwitch CI |
3f9b5c |
+
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_destroy(&new, &type);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_destroy(&old, &type);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_datum_destroy(&diff, &type);
|
|
Open vSwitch CI |
3f9b5c |
@@ -2727,13 +2744,15 @@ print_idl_row_simple2(const struct idltest_simple2 *s, int step)
|
|
Open vSwitch CI |
3f9b5c |
printf("%03d: name=%s smap=[",
|
|
Open vSwitch CI |
3f9b5c |
step, s->name);
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < smap->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
- printf("[%s : %s]%s", smap->keys[i].string, smap->values[i].string,
|
|
Open vSwitch CI |
3f9b5c |
- i < smap->n-1? ",": "");
|
|
Open vSwitch CI |
3f9b5c |
+ printf("[%s : %s]%s",
|
|
Open vSwitch CI |
3f9b5c |
+ smap->keys[i].s->string, smap->values[i].s->string,
|
|
Open vSwitch CI |
3f9b5c |
+ i < smap->n - 1 ? "," : "");
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
printf("] imap=[");
|
|
Open vSwitch CI |
3f9b5c |
for (i = 0; i < imap->n; i++) {
|
|
Open vSwitch CI |
3f9b5c |
- printf("[%"PRId64" : %s]%s", imap->keys[i].integer, imap->values[i].string,
|
|
Open vSwitch CI |
3f9b5c |
- i < imap->n-1? ",":"");
|
|
Open vSwitch CI |
3f9b5c |
+ printf("[%"PRId64" : %s]%s",
|
|
Open vSwitch CI |
3f9b5c |
+ imap->keys[i].integer, imap->values[i].s->string,
|
|
Open vSwitch CI |
3f9b5c |
+ i < imap->n - 1 ? "," : "");
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
printf("]\n");
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
@@ -2802,8 +2821,8 @@ do_idl_partial_update_map_column(struct ovs_cmdl_context *ctx)
|
|
Open vSwitch CI |
3f9b5c |
myTxn = ovsdb_idl_txn_create(idl);
|
|
Open vSwitch CI |
3f9b5c |
smap = idltest_simple2_get_smap(myRow, OVSDB_TYPE_STRING,
|
|
Open vSwitch CI |
3f9b5c |
OVSDB_TYPE_STRING);
|
|
Open vSwitch CI |
3f9b5c |
- strcpy(key_to_delete, smap->keys[0].string);
|
|
Open vSwitch CI |
3f9b5c |
- idltest_simple2_update_smap_delkey(myRow, smap->keys[0].string);
|
|
Open vSwitch CI |
3f9b5c |
+ ovs_strlcpy(key_to_delete, smap->keys[0].s->string, sizeof key_to_delete);
|
|
Open vSwitch CI |
3f9b5c |
+ idltest_simple2_update_smap_delkey(myRow, smap->keys[0].s->string);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_commit_block(myTxn);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_txn_destroy(myTxn);
|
|
Open vSwitch CI |
3f9b5c |
ovsdb_idl_get_initial_snapshot(idl);
|
|
|
110336 |
diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
|
|
Open vSwitch CI |
3f9b5c |
index 48c5de9d19..6364653975 100644
|
|
|
110336 |
--- a/tests/tunnel-push-pop.at
|
|
|
110336 |
+++ b/tests/tunnel-push-pop.at
|
|
Open vSwitch CI |
3f9b5c |
@@ -595,6 +595,64 @@ OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep 50540000000a5054000000091235 | wc
|
|
|
110336 |
OVS_VSWITCHD_STOP
|
|
|
110336 |
AT_CLEANUP
|
|
|
110336 |
|
|
|
110336 |
+AT_SETUP([tunnel_push_pop - packet_out debug_slow])
|
|
|
110336 |
+
|
|
|
110336 |
+OVS_VSWITCHD_START(
|
|
|
110336 |
+ [add-port br0 p0 dnl
|
|
|
110336 |
+ -- set Interface p0 type=dummy ofport_request=1 dnl
|
|
|
110336 |
+ other-config:hwaddr=aa:55:aa:55:00:00])
|
|
|
110336 |
+AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg])
|
|
|
110336 |
+AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br datapath_type=dummy])
|
|
|
110336 |
+AT_CHECK([ovs-vsctl add-port int-br t2 dnl
|
|
|
110336 |
+ -- set Interface t2 type=geneve options:remote_ip=1.1.2.92 dnl
|
|
|
110336 |
+ options:key=123 ofport_request=2])
|
|
|
110336 |
+
|
|
|
110336 |
+dnl First setup dummy interface IP address, then add the route
|
|
|
110336 |
+dnl so that tnl-port table can get valid IP address for the device.
|
|
|
110336 |
+AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK
|
|
|
110336 |
+])
|
|
|
110336 |
+AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK
|
|
|
110336 |
+])
|
|
|
110336 |
+AT_CHECK([ovs-ofctl add-flow br0 action=normal])
|
|
|
110336 |
+
|
|
|
110336 |
+dnl This ARP reply from p0 has two effects:
|
|
|
110336 |
+dnl 1. The ARP cache will learn that 1.1.2.92 is at f8:bc:12:44:34:b6.
|
|
|
110336 |
+dnl 2. The br0 mac learning will learn that f8:bc:12:44:34:b6 is on p0.
|
|
|
110336 |
+AT_CHECK([
|
|
|
110336 |
+ ovs-appctl netdev-dummy/receive p0 dnl
|
|
|
110336 |
+ 'recirc_id(0),in_port(2),dnl
|
|
|
110336 |
+ eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),dnl
|
|
|
110336 |
+ arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)'
|
|
|
110336 |
+])
|
|
|
110336 |
+
|
|
|
110336 |
+AT_CHECK([ovs-vsctl -- set Interface p0 options:tx_pcap=p0.pcap])
|
|
|
110336 |
+
|
|
|
110336 |
+packet=50540000000a505400000009123
|
|
Open vSwitch CI |
3f9b5c |
+dnl Source port is based on a packet hash, so it may differ depending on the
|
|
Open vSwitch CI |
3f9b5c |
+dnl compiler flags and CPU type. Masked with '....'.
|
|
Open vSwitch CI |
3f9b5c |
+encap=f8bc124434b6aa55aa5500000800450000320000400040113406010102580101025c....17c1001e00000000655800007b00
|
|
|
110336 |
+
|
|
|
110336 |
+dnl Output to tunnel from a int-br internal port.
|
|
|
110336 |
+dnl Checking that the packet arrived and it was correctly encapsulated.
|
|
|
110336 |
+AT_CHECK([ovs-ofctl add-flow int-br "in_port=LOCAL,actions=debug_slow,output:2"])
|
|
|
110336 |
+AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"])
|
|
Open vSwitch CI |
3f9b5c |
+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}4" | wc -l` -ge 1])
|
|
|
110336 |
+dnl Sending again to exercise the non-miss upcall path.
|
|
|
110336 |
+AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"])
|
|
Open vSwitch CI |
3f9b5c |
+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}4" | wc -l` -ge 2])
|
|
|
110336 |
+
|
|
|
110336 |
+dnl Output to tunnel from the controller.
|
|
|
110336 |
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out int-br CONTROLLER "debug_slow,output:2" "${packet}5"])
|
|
Open vSwitch CI |
3f9b5c |
+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}5" | wc -l` -ge 1])
|
|
|
110336 |
+
|
|
|
110336 |
+dnl Datapath actions should not have tunnel push action.
|
|
|
110336 |
+AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q tnl_push], [1])
|
|
|
110336 |
+dnl There should be slow_path action instead.
|
|
|
110336 |
+AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q 'slow_path(action)'], [0])
|
|
|
110336 |
+
|
|
|
110336 |
+OVS_VSWITCHD_STOP
|
|
|
110336 |
+AT_CLEANUP
|
|
|
110336 |
+
|
|
|
110336 |
AT_SETUP([tunnel_push_pop - underlay bridge match])
|
|
|
110336 |
|
|
|
110336 |
OVS_VSWITCHD_START([add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1 other-config:hwaddr=aa:55:aa:55:00:00])
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in
|
|
Open vSwitch CI |
3f9b5c |
index 71800795c0..e6e07f4763 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/utilities/ovs-ctl.in
|
|
Open vSwitch CI |
3f9b5c |
+++ b/utilities/ovs-ctl.in
|
|
Open vSwitch CI |
3f9b5c |
@@ -421,7 +421,9 @@ Less important options for "start", "restart" and "force-reload-kmod":
|
|
Open vSwitch CI |
3f9b5c |
--no-force-corefiles do not force on core dumps for OVS daemons
|
|
Open vSwitch CI |
3f9b5c |
--no-mlockall do not lock all of ovs-vswitchd into memory
|
|
Open vSwitch CI |
3f9b5c |
--ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
|
|
Open vSwitch CI |
3f9b5c |
+ --ovsdb-server-options=OPTIONS additional options for ovsdb-server (example: '-vconsole:dbg -vfile:dbg')
|
|
Open vSwitch CI |
3f9b5c |
--ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
|
|
Open vSwitch CI |
3f9b5c |
+ --ovs-vswitchd-options=OPTIONS additional options for ovs-vswitchd (example: '-vconsole:dbg -vfile:dbg')
|
|
Open vSwitch CI |
3f9b5c |
--no-full-hostname set short hostname instead of full hostname
|
|
Open vSwitch CI |
3f9b5c |
--no-record-hostname do not attempt to determine/record system
|
|
Open vSwitch CI |
3f9b5c |
hostname as part of start command
|
|
Open vSwitch CI |
3f9b5c |
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
|
|
Open vSwitch CI |
3f9b5c |
index cb7c5cb769..c790a56adf 100644
|
|
Open vSwitch CI |
3f9b5c |
--- a/vswitchd/bridge.c
|
|
Open vSwitch CI |
3f9b5c |
+++ b/vswitchd/bridge.c
|
|
Open vSwitch CI |
3f9b5c |
@@ -4229,7 +4229,7 @@ bridge_configure_aa(struct bridge *br)
|
|
Open vSwitch CI |
3f9b5c |
union ovsdb_atom atom;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
atom.integer = m->isid;
|
|
Open vSwitch CI |
3f9b5c |
- if (ovsdb_datum_find_key(mc, &atom, OVSDB_TYPE_INTEGER) == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_find_key(mc, &atom, OVSDB_TYPE_INTEGER, NULL)) {
|
|
Open vSwitch CI |
3f9b5c |
VLOG_INFO("Deleting isid=%"PRIu32", vlan=%"PRIu16,
|
|
Open vSwitch CI |
3f9b5c |
m->isid, m->vlan);
|
|
Open vSwitch CI |
3f9b5c |
bridge_aa_mapping_destroy(m);
|
|
Open vSwitch CI |
3f9b5c |
@@ -4826,7 +4826,7 @@ queue_ids_include(const struct ovsdb_datum *queues, int64_t target)
|
|
Open vSwitch CI |
3f9b5c |
union ovsdb_atom atom;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
atom.integer = target;
|
|
Open vSwitch CI |
3f9b5c |
- return ovsdb_datum_find_key(queues, &atom, OVSDB_TYPE_INTEGER) != UINT_MAX;
|
|
Open vSwitch CI |
3f9b5c |
+ return ovsdb_datum_find_key(queues, &atom, OVSDB_TYPE_INTEGER, NULL);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
static void
|
|
Open vSwitch CI |
3f9b5c |
@@ -5020,7 +5020,7 @@ bridge_configure_mirrors(struct bridge *br)
|
|
Open vSwitch CI |
3f9b5c |
union ovsdb_atom atom;
|
|
Open vSwitch CI |
3f9b5c |
|
|
Open vSwitch CI |
3f9b5c |
atom.uuid = m->uuid;
|
|
Open vSwitch CI |
3f9b5c |
- if (ovsdb_datum_find_key(mc, &atom, OVSDB_TYPE_UUID) == UINT_MAX) {
|
|
Open vSwitch CI |
3f9b5c |
+ if (!ovsdb_datum_find_key(mc, &atom, OVSDB_TYPE_UUID, NULL)) {
|
|
Open vSwitch CI |
3f9b5c |
mirror_destroy(m);
|
|
Open vSwitch CI |
3f9b5c |
}
|
|
Open vSwitch CI |
3f9b5c |
}
|