Skip to content
Snippets Groups Projects
Verified Commit 1ab38673 authored by Louis Abel's avatar Louis Abel :tv:
Browse files

import

parent 3833f9b9
No related branches found
No related tags found
No related merge requests found
...@@ -235,10 +235,49 @@ index fd82d7d270..bcee218005 100644 ...@@ -235,10 +235,49 @@ index fd82d7d270..bcee218005 100644
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 4f43369844..e130c2f966 100644 index 4f43369844..592cb7467c 100644
--- a/datapath-windows/ovsext/Actions.c --- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c +++ b/datapath-windows/ovsext/Actions.c
@@ -1550,9 +1550,21 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx, @@ -1112,9 +1112,9 @@ OvsPopFieldInPacketBuf(OvsForwardingContext *ovsFwdCtx,
* should split the function and refactor. */
if (!bufferData) {
EthHdr *ethHdr = (EthHdr *)bufferStart;
- /* If the frame is not VLAN make it a no op */
if (ethHdr->Type != ETH_TYPE_802_1PQ_NBO) {
- return NDIS_STATUS_SUCCESS;
+ OVS_LOG_ERROR("Invalid ethHdr type %u, nbl %p", ethHdr->Type, ovsFwdCtx->curNbl);
+ return NDIS_STATUS_INVALID_PACKET;
}
}
RtlMoveMemory(bufferStart + shiftLength, bufferStart, shiftOffset);
@@ -1137,6 +1137,9 @@ OvsPopFieldInPacketBuf(OvsForwardingContext *ovsFwdCtx,
static __inline NDIS_STATUS
OvsPopVlanInPktBuf(OvsForwardingContext *ovsFwdCtx)
{
+ NDIS_STATUS status;
+ OVS_PACKET_HDR_INFO* layers = &ovsFwdCtx->layers;
+
/*
* Declare a dummy vlanTag structure since we need to compute the size
* of shiftLength. The NDIS one is a unionized structure.
@@ -1145,7 +1148,15 @@ OvsPopVlanInPktBuf(OvsForwardingContext *ovsFwdCtx)
UINT32 shiftLength = sizeof(vlanTag.TagHeader);
UINT32 shiftOffset = sizeof(DL_EUI48) + sizeof(DL_EUI48);
- return OvsPopFieldInPacketBuf(ovsFwdCtx, shiftOffset, shiftLength, NULL);
+ status = OvsPopFieldInPacketBuf(ovsFwdCtx, shiftOffset, shiftLength,
+ NULL);
+
+ if (status == NDIS_STATUS_SUCCESS) {
+ layers->l3Offset -= (UINT16) shiftLength;
+ layers->l4Offset -= (UINT16) shiftLength;
+ }
+
+ return status;
}
@@ -1550,9 +1561,21 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
if (tcpHdr) { if (tcpHdr) {
portField = &tcpHdr->dest; portField = &tcpHdr->dest;
checkField = &tcpHdr->check; checkField = &tcpHdr->check;
...@@ -260,6 +299,137 @@ index 4f43369844..e130c2f966 100644 ...@@ -260,6 +299,137 @@ index 4f43369844..e130c2f966 100644
} }
} }
@@ -1780,9 +1803,11 @@ OvsExecuteRecirc(OvsForwardingContext *ovsFwdCtx,
}
if (newNbl) {
- deferredAction = OvsAddDeferredActions(newNbl, key, NULL);
+ deferredAction = OvsAddDeferredActions(newNbl, key, &(ovsFwdCtx->layers),
+ NULL);
} else {
- deferredAction = OvsAddDeferredActions(ovsFwdCtx->curNbl, key, NULL);
+ deferredAction = OvsAddDeferredActions(ovsFwdCtx->curNbl, key,
+ &(ovsFwdCtx->layers), NULL);
}
if (deferredAction) {
@@ -1952,7 +1977,7 @@ OvsExecuteSampleAction(OvsForwardingContext *ovsFwdCtx,
return STATUS_SUCCESS;
}
- if (!OvsAddDeferredActions(newNbl, key, a)) {
+ if (!OvsAddDeferredActions(newNbl, key, &(ovsFwdCtx->layers), a)) {
OVS_LOG_INFO(
"Deferred actions limit reached, dropping sample action.");
OvsCompleteNBL(ovsFwdCtx->switchContext, newNbl, TRUE);
@@ -2088,6 +2113,7 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
*/
status = OvsPopVlanInPktBuf(&ovsFwdCtx);
if (status != NDIS_STATUS_SUCCESS) {
+ OVS_LOG_ERROR("OVS-pop vlan action failed status = %lu", status);
dropReason = L"OVS-pop vlan action failed";
goto dropit;
}
@@ -2337,7 +2363,7 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext,
if (status == STATUS_SUCCESS) {
status = OvsProcessDeferredActions(switchContext, completionList,
- portNo, sendFlags, layers);
+ portNo, sendFlags, NULL);
}
return status;
diff --git a/datapath-windows/ovsext/Recirc.c b/datapath-windows/ovsext/Recirc.c
index 2febf060dd..a32b75352b 100644
--- a/datapath-windows/ovsext/Recirc.c
+++ b/datapath-windows/ovsext/Recirc.c
@@ -277,16 +277,23 @@ OvsDeferredActionsQueuePush(POVS_DEFERRED_ACTION_QUEUE queue)
POVS_DEFERRED_ACTION
OvsAddDeferredActions(PNET_BUFFER_LIST nbl,
OvsFlowKey *key,
+ POVS_PACKET_HDR_INFO layers,
const PNL_ATTR actions)
{
POVS_DEFERRED_ACTION_QUEUE queue = OvsDeferredActionsQueueGet();
POVS_DEFERRED_ACTION deferredAction = NULL;
+ OVS_PACKET_HDR_INFO layersInit = { 0 };
deferredAction = OvsDeferredActionsQueuePush(queue);
if (deferredAction) {
deferredAction->nbl = nbl;
deferredAction->actions = actions;
deferredAction->key = *key;
+ if (layers) {
+ deferredAction->layers = *layers;
+ } else {
+ deferredAction->layers = layersInit;
+ }
}
return deferredAction;
@@ -309,9 +316,16 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
POVS_DEFERRED_ACTION_QUEUE queue = OvsDeferredActionsQueueGet();
POVS_DEFERRED_ACTION deferredAction = NULL;
+ POVS_PACKET_HDR_INFO layersDeferred = NULL;
/* Process all deferred actions. */
while ((deferredAction = OvsDeferredActionsQueuePop(queue)) != NULL) {
+ if (layers) {
+ layersDeferred = layers;
+ } else {
+ layersDeferred = &(deferredAction->layers);
+ }
+
if (deferredAction->actions) {
status = OvsDoExecuteActions(switchContext,
completionList,
@@ -319,7 +333,7 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
portNo,
sendFlags,
&deferredAction->key, NULL,
- layers, deferredAction->actions,
+ layersDeferred, deferredAction->actions,
NlAttrGetSize(deferredAction->actions));
} else {
status = OvsDoRecirc(switchContext,
@@ -327,7 +341,7 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
deferredAction->nbl,
&deferredAction->key,
portNo,
- layers);
+ layersDeferred);
}
}
diff --git a/datapath-windows/ovsext/Recirc.h b/datapath-windows/ovsext/Recirc.h
index 2b314ce274..74130a4600 100644
--- a/datapath-windows/ovsext/Recirc.h
+++ b/datapath-windows/ovsext/Recirc.h
@@ -18,6 +18,7 @@
#define __RECIRC_H_ 1
#include "Actions.h"
+#include "NetProto.h"
#define DEFERRED_ACTION_QUEUE_SIZE 10
#define DEFERRED_ACTION_EXEC_LEVEL 4
@@ -26,6 +27,7 @@ typedef struct _OVS_DEFERRED_ACTION {
PNET_BUFFER_LIST nbl;
PNL_ATTR actions;
OvsFlowKey key;
+ OVS_PACKET_HDR_INFO layers;
} OVS_DEFERRED_ACTION, *POVS_DEFERRED_ACTION;
/*
@@ -52,6 +54,7 @@ OvsProcessDeferredActions(POVS_SWITCH_CONTEXT switchContext,
POVS_DEFERRED_ACTION
OvsAddDeferredActions(PNET_BUFFER_LIST packet,
OvsFlowKey *key,
+ POVS_PACKET_HDR_INFO layers,
const PNL_ATTR actions);
/*
diff --git a/datapath-windows/ovsext/ovsext.vcxproj b/datapath-windows/ovsext/ovsext.vcxproj diff --git a/datapath-windows/ovsext/ovsext.vcxproj b/datapath-windows/ovsext/ovsext.vcxproj
index d50a126b43..18f884f41b 100644 index d50a126b43..18f884f41b 100644
--- a/datapath-windows/ovsext/ovsext.vcxproj --- a/datapath-windows/ovsext/ovsext.vcxproj
...@@ -18347,6 +18517,18 @@ index b0a5ce8bec..bc51a5767f 100644 ...@@ -18347,6 +18517,18 @@ index b0a5ce8bec..bc51a5767f 100644
}; };
enum { enum {
diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
index 95e52e3587..045dce8f5f 100644
--- a/include/openvswitch/meta-flow.h
+++ b/include/openvswitch/meta-flow.h
@@ -2305,6 +2305,7 @@ void mf_set_flow_value_masked(const struct mf_field *,
const union mf_value *mask,
struct flow *);
bool mf_is_tun_metadata(const struct mf_field *);
+bool mf_is_frozen_metadata(const struct mf_field *);
bool mf_is_pipeline_field(const struct mf_field *);
bool mf_is_set(const struct mf_field *, const struct flow *);
void mf_mask_field(const struct mf_field *, struct flow_wildcards *);
diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in
index 64111768b3..668507fd37 100755 index 64111768b3..668507fd37 100755
--- a/ipsec/ovs-monitor-ipsec.in --- a/ipsec/ovs-monitor-ipsec.in
...@@ -18647,8 +18829,21 @@ index 9e2d06b3dd..4e02425f7c 100644 ...@@ -18647,8 +18829,21 @@ index 9e2d06b3dd..4e02425f7c 100644
} }
static inline void static inline void
diff --git a/lib/dpdk-stub.c b/lib/dpdk-stub.c
index b7d577870d..fe24f9abdf 100644
--- a/lib/dpdk-stub.c
+++ b/lib/dpdk-stub.c
@@ -83,7 +83,7 @@ bool
dpdk_get_cpu_has_isa(const char *arch OVS_UNUSED,
const char *feature OVS_UNUSED)
{
- VLOG_ERR_ONCE("DPDK not supported in this version of Open vSwitch, "
+ VLOG_DBG_ONCE("DPDK not supported in this version of Open vSwitch, "
"cannot use CPU flag based optimizations");
return false;
}
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 4381c618f1..3026a0619f 100644 index 4381c618f1..a07a34b89a 100644
--- a/lib/dpif-netdev.c --- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c
@@ -279,8 +279,9 @@ static bool dpcls_lookup(struct dpcls *cls, @@ -279,8 +279,9 @@ static bool dpcls_lookup(struct dpcls *cls,
...@@ -18895,22 +19090,32 @@ index 4381c618f1..3026a0619f 100644 ...@@ -18895,22 +19090,32 @@ index 4381c618f1..3026a0619f 100644
dp_netdev_execute_actions(pmd, &pp, false, execute->flow, dp_netdev_execute_actions(pmd, &pp, false, execute->flow,
execute->actions, execute->actions_len); execute->actions, execute->actions_len);
dp_netdev_pmd_flush_output_packets(pmd, true); dp_netdev_pmd_flush_output_packets(pmd, true);
@@ -4169,6 +4152,14 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute) @@ -4169,6 +4152,24 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
dp_netdev_pmd_unref(pmd); dp_netdev_pmd_unref(pmd);
} }
+ if (dp_packet_batch_size(&pp)) { + if (dp_packet_batch_size(&pp) == 1) {
+ /* Packet wasn't dropped during the execution. Swapping content with + /* Packet wasn't dropped during the execution. Swapping content with
+ * the original packet, because the caller might expect actions to + * the original packet, because the caller might expect actions to
+ * modify it. */ + * modify it. Uisng the packet from a batch instead of 'packet_clone'
+ dp_packet_swap(execute->packet, packet_clone); + * because it maybe stolen and replaced by other packet, e.g. by
+ * the fragmentation engine. */
+ dp_packet_swap(execute->packet, pp.packets[0]);
+ dp_packet_delete_batch(&pp, true);
+ } else if (dp_packet_batch_size(&pp)) {
+ /* FIXME: We have more packets than expected. Likely, we got IP
+ * fragments of the reassembled packet. Dropping them here as we have
+ * no way to get them to the caller. It might be that all the required
+ * actions with them are already executed, but it also might not be a
+ * case, e.g. if dpif_netdev_execute() called to execute a single
+ * tunnel push. */
+ dp_packet_delete_batch(&pp, true); + dp_packet_delete_batch(&pp, true);
+ } + }
+ +
return 0; return 0;
} }
@@ -4878,6 +4869,12 @@ struct rr_numa { @@ -4878,6 +4879,12 @@ struct rr_numa {
bool idx_inc; bool idx_inc;
}; };
...@@ -18923,7 +19128,7 @@ index 4381c618f1..3026a0619f 100644 ...@@ -18923,7 +19128,7 @@ index 4381c618f1..3026a0619f 100644
static struct rr_numa * static struct rr_numa *
rr_numa_list_lookup(struct rr_numa_list *rr, int numa_id) rr_numa_list_lookup(struct rr_numa_list *rr, int numa_id)
{ {
@@ -5149,7 +5146,6 @@ reload_affected_pmds(struct dp_netdev *dp) @@ -5149,7 +5156,6 @@ reload_affected_pmds(struct dp_netdev *dp)
CMAP_FOR_EACH (pmd, node, &dp->poll_threads) { CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
if (pmd->need_reload) { if (pmd->need_reload) {
...@@ -18931,7 +19136,7 @@ index 4381c618f1..3026a0619f 100644 ...@@ -18931,7 +19136,7 @@ index 4381c618f1..3026a0619f 100644
dp_netdev_reload_pmd__(pmd); dp_netdev_reload_pmd__(pmd);
} }
} }
@@ -5590,10 +5586,17 @@ get_dry_run_variance(struct dp_netdev *dp, uint32_t *core_list, @@ -5590,10 +5596,17 @@ get_dry_run_variance(struct dp_netdev *dp, uint32_t *core_list,
for (int i = 0; i < n_rxqs; i++) { for (int i = 0; i < n_rxqs; i++) {
int numa_id = netdev_get_numa_id(rxqs[i]->port->netdev); int numa_id = netdev_get_numa_id(rxqs[i]->port->netdev);
numa = rr_numa_list_lookup(&rr, numa_id); numa = rr_numa_list_lookup(&rr, numa_id);
...@@ -18952,7 +19157,7 @@ index 4381c618f1..3026a0619f 100644 ...@@ -18952,7 +19157,7 @@ index 4381c618f1..3026a0619f 100644
goto cleanup; goto cleanup;
} }
@@ -6203,12 +6206,14 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, @@ -6203,12 +6216,14 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_,
/* Update all bands and find the one hit with the highest rate for each /* Update all bands and find the one hit with the highest rate for each
* packet (if any). */ * packet (if any). */
for (int m = 0; m < meter->n_bands; ++m) { for (int m = 0; m < meter->n_bands; ++m) {
...@@ -18971,7 +19176,7 @@ index 4381c618f1..3026a0619f 100644 ...@@ -18971,7 +19176,7 @@ index 4381c618f1..3026a0619f 100644
} }
/* Drain the bucket for all the packets, if possible. */ /* Drain the bucket for all the packets, if possible. */
@@ -6226,8 +6231,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, @@ -6226,8 +6241,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_,
* (Only one band will be fired by a packet, and that * (Only one band will be fired by a packet, and that
* can be different for each packet.) */ * can be different for each packet.) */
for (int i = band_exceeded_pkt; i < cnt; i++) { for (int i = band_exceeded_pkt; i < cnt; i++) {
...@@ -18982,7 +19187,7 @@ index 4381c618f1..3026a0619f 100644 ...@@ -18982,7 +19187,7 @@ index 4381c618f1..3026a0619f 100644
exceeded_band[i] = m; exceeded_band[i] = m;
} }
} }
@@ -6246,8 +6251,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, @@ -6246,8 +6261,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_,
/* Update the exceeding band for the exceeding packet. /* Update the exceeding band for the exceeding packet.
* (Only one band will be fired by a packet, and that * (Only one band will be fired by a packet, and that
* can be different for each packet.) */ * can be different for each packet.) */
...@@ -18993,7 +19198,7 @@ index 4381c618f1..3026a0619f 100644 ...@@ -18993,7 +19198,7 @@ index 4381c618f1..3026a0619f 100644
exceeded_band[i] = m; exceeded_band[i] = m;
} }
} }
@@ -6329,16 +6334,14 @@ dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id meter_id, @@ -6329,16 +6344,14 @@ dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id meter_id,
config->bands[i].burst_size = config->bands[i].rate; config->bands[i].burst_size = config->bands[i].rate;
} }
...@@ -19015,7 +19220,7 @@ index 4381c618f1..3026a0619f 100644 ...@@ -19015,7 +19220,7 @@ index 4381c618f1..3026a0619f 100644
if (band_max_delta_t > meter->max_delta_t) { if (band_max_delta_t > meter->max_delta_t) {
meter->max_delta_t = band_max_delta_t; meter->max_delta_t = band_max_delta_t;
} }
@@ -8493,6 +8496,7 @@ const struct dpif_class dpif_netdev_class = { @@ -8493,6 +8506,7 @@ const struct dpif_class dpif_netdev_class = {
NULL, /* ct_timeout_policy_dump_next */ NULL, /* ct_timeout_policy_dump_next */
NULL, /* ct_timeout_policy_dump_done */ NULL, /* ct_timeout_policy_dump_done */
dpif_netdev_ct_get_timeout_policy_name, dpif_netdev_ct_get_timeout_policy_name,
...@@ -19205,7 +19410,7 @@ index 6f7b610a99..fd0127ed17 100644 ...@@ -19205,7 +19410,7 @@ index 6f7b610a99..fd0127ed17 100644
dst->allocated = dst->length; dst->allocated = dst->length;
dst->string = xmalloc(dst->allocated + 1); dst->string = xmalloc(dst->allocated + 1);
diff --git a/lib/ipf.c b/lib/ipf.c diff --git a/lib/ipf.c b/lib/ipf.c
index c20bcc0b33..24325a638d 100644 index c20bcc0b33..009f5d1e9b 100644
--- a/lib/ipf.c --- a/lib/ipf.c
+++ b/lib/ipf.c +++ b/lib/ipf.c
@@ -93,7 +93,6 @@ struct ipf_frag { @@ -93,7 +93,6 @@ struct ipf_frag {
...@@ -19257,7 +19462,7 @@ index c20bcc0b33..24325a638d 100644 ...@@ -19257,7 +19462,7 @@ index c20bcc0b33..24325a638d 100644
} }
/* Filters out fragments from a batch of fragments and adjust the batch. */ /* Filters out fragments from a batch of fragments and adjust the batch. */
@@ -942,8 +938,7 @@ ipf_extract_frags_from_batch(struct ipf *ipf, struct dp_packet_batch *pb, @@ -942,9 +938,10 @@ ipf_extract_frags_from_batch(struct ipf *ipf, struct dp_packet_batch *pb,
ipf_is_valid_v6_frag(ipf, pkt)))) { ipf_is_valid_v6_frag(ipf, pkt)))) {
ovs_mutex_lock(&ipf->ipf_lock); ovs_mutex_lock(&ipf->ipf_lock);
...@@ -19265,9 +19470,12 @@ index c20bcc0b33..24325a638d 100644 ...@@ -19265,9 +19470,12 @@ index c20bcc0b33..24325a638d 100644
- pb->do_not_steal)) { - pb->do_not_steal)) {
+ if (!ipf_handle_frag(ipf, pkt, dl_type, zone, now, hash_basis)) { + if (!ipf_handle_frag(ipf, pkt, dl_type, zone, now, hash_basis)) {
dp_packet_batch_refill(pb, pkt, pb_idx); dp_packet_batch_refill(pb, pkt, pb_idx);
+ } else {
+ dp_packet_delete(pkt);
} }
ovs_mutex_unlock(&ipf->ipf_lock); ovs_mutex_unlock(&ipf->ipf_lock);
@@ -1154,52 +1149,56 @@ ipf_post_execute_reass_pkts(struct ipf *ipf, } else {
@@ -1154,52 +1151,56 @@ ipf_post_execute_reass_pkts(struct ipf *ipf,
* NETDEV_MAX_BURST. */ * NETDEV_MAX_BURST. */
DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) { DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) {
if (rp && pkt == rp->list->reass_execute_ctx) { if (rp && pkt == rp->list->reass_execute_ctx) {
...@@ -19362,7 +19570,7 @@ index c20bcc0b33..24325a638d 100644 ...@@ -19362,7 +19570,7 @@ index c20bcc0b33..24325a638d 100644
} }
ipf_completed_list_add(&ipf->frag_complete_list, rp->list); ipf_completed_list_add(&ipf->frag_complete_list, rp->list);
@@ -1338,9 +1337,7 @@ ipf_destroy(struct ipf *ipf) @@ -1338,9 +1339,7 @@ ipf_destroy(struct ipf *ipf)
while (ipf_list->last_sent_idx < ipf_list->last_inuse_idx) { while (ipf_list->last_sent_idx < ipf_list->last_inuse_idx) {
struct dp_packet *pkt struct dp_packet *pkt
= ipf_list->frag_list[ipf_list->last_sent_idx + 1].pkt; = ipf_list->frag_list[ipf_list->last_sent_idx + 1].pkt;
...@@ -19414,6 +19622,30 @@ index d75d66b863..ba096dd0c8 100644 ...@@ -19414,6 +19622,30 @@ index d75d66b863..ba096dd0c8 100644
void jsonrpc_session_set_max_backoff(struct jsonrpc_session *, void jsonrpc_session_set_max_backoff(struct jsonrpc_session *,
int max_backoff); int max_backoff);
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index c808d205d5..e03cd8d0c5 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -1788,6 +1788,19 @@ mf_is_tun_metadata(const struct mf_field *mf)
mf->id < MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS;
}
+bool
+mf_is_frozen_metadata(const struct mf_field *mf)
+{
+ if (mf->id >= MFF_TUN_ID && mf->id <= MFF_IN_PORT_OXM) {
+ return true;
+ }
+
+ if (mf->id >= MFF_REG0 && mf->id < MFF_ETH_SRC) {
+ return true;
+ }
+ return false;
+}
+
bool
mf_is_pipeline_field(const struct mf_field *mf)
{
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 9d8096668e..6699c383e6 100644 index 9d8096668e..6699c383e6 100644
--- a/lib/netdev-dpdk.c --- a/lib/netdev-dpdk.c
...@@ -20772,10 +21004,58 @@ index 5fae46adfc..ccf97266c0 100644 ...@@ -20772,10 +21004,58 @@ index 5fae46adfc..ccf97266c0 100644
ovs_mutex_destroy(&udpif->ukeys[i].mutex); ovs_mutex_destroy(&udpif->ukeys[i].mutex);
} }
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 7108c8a301..479e459fcb 100644 index 7108c8a301..3942ddbdc7 100644
--- a/ofproto/ofproto-dpif-xlate.c --- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c
@@ -7127,7 +7127,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, @@ -6177,11 +6177,32 @@ static void
compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
bool is_last_action)
{
- ovs_u128 old_ct_label_mask = ctx->wc->masks.ct_label;
- uint32_t old_ct_mark_mask = ctx->wc->masks.ct_mark;
- size_t ct_offset;
uint16_t zone;
+ if (ofc->zone_src.field) {
+ union mf_subvalue value;
+ memset(&value, 0xff, sizeof(value));
+ zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow);
+ if (ctx->xin->frozen_state) {
+ /* If the upcall is a resume of a recirculation, we only need to
+ * unwildcard the fields that are not in the frozen_metadata, as
+ * when the rules update, OVS will generate a new recirc_id,
+ * which will invalidate the megaflow with old the recirc_id.
+ */
+ if (!mf_is_frozen_metadata(ofc->zone_src.field)) {
+ mf_write_subfield_flow(&ofc->zone_src, &value,
+ &ctx->wc->masks);
+ }
+ } else {
+ mf_write_subfield_flow(&ofc->zone_src, &value, &ctx->wc->masks);
+ }
+ } else {
+ zone = ofc->zone_imm;
+ }
+
+ size_t ct_offset;
+ ovs_u128 old_ct_label_mask = ctx->wc->masks.ct_label;
+ uint32_t old_ct_mark_mask = ctx->wc->masks.ct_mark;
/* Ensure that any prior actions are applied before composing the new
* conntrack action. */
xlate_commit_actions(ctx);
@@ -6193,11 +6214,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc,
do_xlate_actions(ofc->actions, ofpact_ct_get_action_len(ofc), ctx,
is_last_action, false);
- if (ofc->zone_src.field) {
- zone = mf_get_subfield(&ofc->zone_src, &ctx->xin->flow);
- } else {
- zone = ofc->zone_imm;
- }
ct_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CT);
if (ofc->flags & NX_CT_F_COMMIT) {
@@ -7127,7 +7143,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
break; break;
case OFPACT_CT_CLEAR: case OFPACT_CT_CLEAR:
...@@ -21162,7 +21442,7 @@ index 8aec6bbac1..ba55566926 100644 ...@@ -21162,7 +21442,7 @@ index 8aec6bbac1..ba55566926 100644
from collections import Sequence, MutableSequence from collections import Sequence, MutableSequence
from functools import wraps from functools import wraps
diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
index 5850ac7abf..6cb5bef10b 100644 index 5850ac7abf..3ca47f96bb 100644
--- a/python/ovs/db/idl.py --- a/python/ovs/db/idl.py
+++ b/python/ovs/db/idl.py +++ b/python/ovs/db/idl.py
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
...@@ -21368,6 +21648,18 @@ index 5850ac7abf..6cb5bef10b 100644 ...@@ -21368,6 +21648,18 @@ index 5850ac7abf..6cb5bef10b 100644
def __check_server_db(self): def __check_server_db(self):
"""Returns True if this is a valid server database, False otherwise.""" """Returns True if this is a valid server database, False otherwise."""
@@ -1458,6 +1479,11 @@ class Transaction(object):
if self != self.idl.txn:
return self._status
+ if self.idl.state != Idl.IDL_S_MONITORING:
+ self._status = Transaction.TRY_AGAIN
+ self.__disassemble()
+ return self._status
+
# If we need a lock but don't have it, give up quickly.
if self.idl.lock_name and not self.idl.has_lock:
self._status = Transaction.NOT_LOCKED
diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py
index bf32f8c87c..d5127268aa 100644 index bf32f8c87c..d5127268aa 100644
--- a/python/ovs/jsonrpc.py --- a/python/ovs/jsonrpc.py
...@@ -23390,7 +23682,7 @@ index 4f601ef939..c8e4c68fae 100644 ...@@ -23390,7 +23682,7 @@ index 4f601ef939..c8e4c68fae 100644
+OVS_TRAFFIC_VSWITCHD_STOP +OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP +AT_CLEANUP
diff --git a/tests/system-traffic.at b/tests/system-traffic.at diff --git a/tests/system-traffic.at b/tests/system-traffic.at
index fb5b9a36d2..bc203c1cce 100644 index fb5b9a36d2..b56ffda448 100644
--- a/tests/system-traffic.at --- a/tests/system-traffic.at
+++ b/tests/system-traffic.at +++ b/tests/system-traffic.at
@@ -574,6 +574,60 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PI @@ -574,6 +574,60 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PI
...@@ -23454,7 +23746,119 @@ index fb5b9a36d2..bc203c1cce 100644 ...@@ -23454,7 +23746,119 @@ index fb5b9a36d2..bc203c1cce 100644
AT_SETUP([datapath - flow resume with geneve tun_metadata]) AT_SETUP([datapath - flow resume with geneve tun_metadata])
OVS_CHECK_GENEVE() OVS_CHECK_GENEVE()
@@ -3251,6 +3305,46 @@ NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING @@ -1927,6 +1981,111 @@ tcp,orig=(src=10.1.1.3,dst=10.1.1.4,sport=<cleared>,dport=<cleared>),reply=(src=
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
+AT_SETUP([conntrack - zones from other field])
+CHECK_CONNTRACK()
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0.
+AT_DATA([flows.txt], [dnl
+priority=1,action=drop
+priority=10,arp,action=normal
+priority=10,icmp,action=normal
+priority=100,in_port=1,tcp,ct_state=-trk,action=ct(zone=5,table=0)
+priority=100,in_port=1,tcp,ct_state=+trk,action=ct(commit,zone=NXM_NX_CT_ZONE[]),2
+priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0,zone=5)
+priority=100,in_port=2,ct_state=+trk,ct_zone=5,tcp,action=1
+])
+
+AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
+
+OVS_START_L7([at_ns1], [http])
+
+dnl HTTP requests from p0->p1 should work fine.
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
+tcp,dnl
+orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),dnl
+reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),dnl
+zone=5,protoinfo=(state=<cleared>)
+])
+
+dnl This is to test when the zoneid is set by a field variable like
+dnl NXM_NX_CT_ZONE, the OVS xlate should generate a megaflow with a form of
+dnl "ct_zone(5), ... actions: ct(commit, zone=5)". The match "ct_zone(5)"
+dnl is needed as if we changes the zoneid into 15 in the following, the old
+dnl "ct_zone(5), ... actions: ct(commit, zone=5)" megaflow will not get hit,
+dnl and OVS will generate a new megaflow with the match "ct_zone(0xf)".
+dnl This will make sure that the new packets are committing to zoneid 15
+dnl rather than old 5.
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
+ | grep "+trk" | grep -q "ct_zone(0x5)" ], [0], [])
+
+AT_CHECK([ovs-ofctl mod-flows br0 dnl
+ 'priority=100,ct_state=-trk,tcp,in_port="ovs-p0" actions=ct(table=0,zone=15)'])
+
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
+ | grep "+trk" | grep -q "ct_zone(0xf)" ], [0], [])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([conntrack - zones from other field, more tests])
+CHECK_CONNTRACK()
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0.
+AT_DATA([flows.txt], [dnl
+priority=1,action=drop
+priority=10,arp,action=normal
+priority=10,icmp,action=normal
+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]]))
+priority=100,in_port=1,tcp,ct_state=+trk,action=ct(commit,zone=NXM_NX_CT_LABEL[[0..15]]),2
+priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0,zone=5)
+priority=100,in_port=2,ct_state=+trk,ct_zone=5,tcp,action=1
+])
+
+AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
+
+OVS_START_L7([at_ns1], [http])
+
+dnl HTTP requests from p0->p1 should work fine.
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
+tcp,dnl
+orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),dnl
+reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),dnl
+zone=5,labels=0xffff0005,protoinfo=(state=<cleared>)
+])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
+ | grep "+trk" | sed 's/0xffff0005\/0xffff/0x5\/0xffff/' dnl
+ | grep -q "ct_label(0x5/0xffff)" ], [0], [])
+
+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]]))'])
+
+NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows --names filter=in_port=ovs-p0 dnl
+ | grep "+trk" | sed 's/0xffff000f\/0xffff/0xf\/0xffff/' dnl
+ | grep -q "ct_label(0xf/0xffff)" ], [0], [])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
AT_SETUP([conntrack - multiple bridges])
CHECK_CONNTRACK()
OVS_TRAFFIC_VSWITCHD_START(
@@ -3251,6 +3410,46 @@ NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING
OVS_TRAFFIC_VSWITCHD_STOP OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP AT_CLEANUP
...@@ -23501,7 +23905,7 @@ index fb5b9a36d2..bc203c1cce 100644 ...@@ -23501,7 +23905,7 @@ index fb5b9a36d2..bc203c1cce 100644
AT_SETUP([conntrack - resubmit to ct multiple times]) AT_SETUP([conntrack - resubmit to ct multiple times])
CHECK_CONNTRACK() CHECK_CONNTRACK()
@@ -4433,6 +4527,52 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src= @@ -4433,6 +4632,52 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=
OVS_TRAFFIC_VSWITCHD_STOP OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP AT_CLEANUP
...@@ -23554,7 +23958,7 @@ index fb5b9a36d2..bc203c1cce 100644 ...@@ -23554,7 +23958,7 @@ index fb5b9a36d2..bc203c1cce 100644
AT_SETUP([conntrack - simple DNAT]) AT_SETUP([conntrack - simple DNAT])
CHECK_CONNTRACK() CHECK_CONNTRACK()
CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_NAT()
@@ -4488,6 +4628,41 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src= @@ -4488,6 +4733,41 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=
OVS_TRAFFIC_VSWITCHD_STOP OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP AT_CLEANUP
...@@ -24243,10 +24647,10 @@ index f0ad9f9793..cea48eb527 100644 ...@@ -24243,10 +24647,10 @@ index f0ad9f9793..cea48eb527 100644
import sys import sys
diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
index 48c5de9d19..12fc1ef910 100644 index 48c5de9d19..6364653975 100644
--- a/tests/tunnel-push-pop.at --- a/tests/tunnel-push-pop.at
+++ b/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at
@@ -595,6 +595,62 @@ OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep 50540000000a5054000000091235 | wc @@ -595,6 +595,64 @@ OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep 50540000000a5054000000091235 | wc
OVS_VSWITCHD_STOP OVS_VSWITCHD_STOP
AT_CLEANUP AT_CLEANUP
...@@ -24283,20 +24687,22 @@ index 48c5de9d19..12fc1ef910 100644 ...@@ -24283,20 +24687,22 @@ index 48c5de9d19..12fc1ef910 100644
+AT_CHECK([ovs-vsctl -- set Interface p0 options:tx_pcap=p0.pcap]) +AT_CHECK([ovs-vsctl -- set Interface p0 options:tx_pcap=p0.pcap])
+ +
+packet=50540000000a505400000009123 +packet=50540000000a505400000009123
+encap=f8bc124434b6aa55aa5500000800450000320000400040113406010102580101025c83a917c1001e00000000655800007b00 +dnl Source port is based on a packet hash, so it may differ depending on the
+dnl compiler flags and CPU type. Masked with '....'.
+encap=f8bc124434b6aa55aa5500000800450000320000400040113406010102580101025c....17c1001e00000000655800007b00
+ +
+dnl Output to tunnel from a int-br internal port. +dnl Output to tunnel from a int-br internal port.
+dnl Checking that the packet arrived and it was correctly encapsulated. +dnl Checking that the packet arrived and it was correctly encapsulated.
+AT_CHECK([ovs-ofctl add-flow int-br "in_port=LOCAL,actions=debug_slow,output:2"]) +AT_CHECK([ovs-ofctl add-flow int-br "in_port=LOCAL,actions=debug_slow,output:2"])
+AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"]) +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"])
+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep "${encap}${packet}4" | wc -l` -ge 1]) +OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}4" | wc -l` -ge 1])
+dnl Sending again to exercise the non-miss upcall path. +dnl Sending again to exercise the non-miss upcall path.
+AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"]) +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}4"])
+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep "${encap}${packet}4" | wc -l` -ge 2]) +OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}4" | wc -l` -ge 2])
+ +
+dnl Output to tunnel from the controller. +dnl Output to tunnel from the controller.
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out int-br CONTROLLER "debug_slow,output:2" "${packet}5"]) +AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out int-br CONTROLLER "debug_slow,output:2" "${packet}5"])
+OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | grep "${encap}${packet}5" | wc -l` -ge 1]) +OVS_WAIT_UNTIL([test `ovs-pcap p0.pcap | egrep "${encap}${packet}5" | wc -l` -ge 1])
+ +
+dnl Datapath actions should not have tunnel push action. +dnl Datapath actions should not have tunnel push action.
+AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q tnl_push], [1]) +AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q tnl_push], [1])
......
...@@ -57,7 +57,7 @@ Summary: Open vSwitch ...@@ -57,7 +57,7 @@ Summary: Open vSwitch
Group: System Environment/Daemons daemon/database/utilities Group: System Environment/Daemons daemon/database/utilities
URL: http://www.openvswitch.org/ URL: http://www.openvswitch.org/
Version: 2.15.0 Version: 2.15.0
Release: 41%{?dist} Release: 47%{?dist}
# Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the
# lib/sflow*.[ch] files are SISSL # lib/sflow*.[ch] files are SISSL
...@@ -699,6 +699,44 @@ exit 0 ...@@ -699,6 +699,44 @@ exit 0
%endif %endif
%changelog %changelog
* Tue Oct 19 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-47
- Merging upstream branch-2.15 [RH git: 01110b9088]
Commit list:
b7d9c491ec datapath-windows: add layers when adding the deferred actions
* Thu Oct 14 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-46
- Merging upstream branch-2.15 [RH git: f8619036c9]
Commit list:
3f718857e7 ofproto-dpif-xlate: Fix zone set from non-frozen-metadata fields.
* Wed Oct 13 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-45
- Merging upstream branch-2.15 [RH git: e273e307d1]
Commit list:
ea2ca0af16 dpif-netdev: Fix use-after-free on PACKET_OUT of IP fragments.
9f964354e3 tunnel-push-pop.at: Mask source port in tunnel header.
* Tue Oct 12 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-44
- Merging upstream branch-2.15 [RH git: 3050e5222d]
Commit list:
58397f222b dpdk-stub: Change the ERR log to DBG.
2a963fc314 python: idl: Avoid sending transactions when the DB is not synced up.
* Tue Oct 12 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-43
- Merging upstream branch-2.15 [RH git: 09e3ab3630]
Commit list:
9efa2ea619 ipf: release unhandled packets from the batch
* Thu Sep 30 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-42
- Merging upstream branch-2.15 [RH git: 2a86017f3f]
Commit list:
f8274b78c3 datapath-windows:adjust Offset when processing packet in POP_VLAN action
* Mon Sep 27 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-41 * Mon Sep 27 2021 Open vSwitch CI <ovs-ci@redhat.com> - 2.15.0-41
- Merging upstream branch-2.15 [RH git: 8f2e30f011] - Merging upstream branch-2.15 [RH git: 8f2e30f011]
Commit list: Commit list:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment